]> git.proxmox.com Git - mirror_qemu.git/blob - target-sh4/translate.c
SH4: Fix bugs introduce in r5099
[mirror_qemu.git] / target-sh4 / translate.c
1 /*
2 * SH4 translation
3 *
4 * Copyright (c) 2005 Samuel Tardieu
5 *
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public
8 * License as published by the Free Software Foundation; either
9 * version 2 of the License, or (at your option) any later version.
10 *
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Lesser General Public License for more details.
15 *
16 * You should have received a copy of the GNU Lesser General Public
17 * License along with this library; if not, 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"
34 #include "helper.h"
35 #include "tcg-op.h"
36 #include "qemu-common.h"
37
38 typedef struct DisasContext {
39 struct TranslationBlock *tb;
40 target_ulong pc;
41 uint32_t sr;
42 uint32_t fpscr;
43 uint16_t opcode;
44 uint32_t flags;
45 int bstate;
46 int memidx;
47 uint32_t delayed_pc;
48 int singlestep_enabled;
49 } DisasContext;
50
51 enum {
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
60 /* global register indexes */
61 static TCGv cpu_env;
62 static TCGv cpu_gregs[24];
63
64 /* dyngen register indexes */
65 static TCGv cpu_T[2];
66
67 #include "gen-icount.h"
68
69 static void sh4_translate_init(void)
70 {
71 int i;
72 static int done_init = 0;
73 static const char * const gregnames[24] = {
74 "R0_BANK0", "R1_BANK0", "R2_BANK0", "R3_BANK0",
75 "R4_BANK0", "R5_BANK0", "R6_BANK0", "R7_BANK0",
76 "R8", "R9", "R10", "R11", "R12", "R13", "R14", "R15",
77 "R0_BANK1", "R1_BANK1", "R2_BANK1", "R3_BANK1",
78 "R4_BANK1", "R5_BANK1", "R6_BANK1", "R7_BANK1"
79 };
80
81 if (done_init)
82 return;
83
84 cpu_env = tcg_global_reg_new(TCG_TYPE_PTR, TCG_AREG0, "env");
85 cpu_T[0] = tcg_global_reg_new(TCG_TYPE_I32, TCG_AREG1, "T0");
86 cpu_T[1] = tcg_global_reg_new(TCG_TYPE_I32, TCG_AREG2, "T1");
87
88 for (i = 0; i < 24; i++)
89 cpu_gregs[i] = tcg_global_mem_new(TCG_TYPE_I32, TCG_AREG0,
90 offsetof(CPUState, gregs[i]),
91 gregnames[i]);
92
93 /* register helpers */
94 #undef DEF_HELPER
95 #define DEF_HELPER(ret, name, params) tcg_register_helper(name, #name);
96 #include "helper.h"
97
98 done_init = 1;
99 }
100
101 #ifdef CONFIG_USER_ONLY
102
103 #define GEN_OP_LD(width, reg) \
104 void gen_op_ld##width##_T0_##reg (DisasContext *ctx) { \
105 gen_op_ld##width##_T0_##reg##_raw(); \
106 }
107 #define GEN_OP_ST(width, reg) \
108 void gen_op_st##width##_##reg##_T1 (DisasContext *ctx) { \
109 gen_op_st##width##_##reg##_T1_raw(); \
110 }
111
112 #else
113
114 #define GEN_OP_LD(width, reg) \
115 void gen_op_ld##width##_T0_##reg (DisasContext *ctx) { \
116 if (ctx->memidx) gen_op_ld##width##_T0_##reg##_kernel(); \
117 else gen_op_ld##width##_T0_##reg##_user();\
118 }
119 #define GEN_OP_ST(width, reg) \
120 void gen_op_st##width##_##reg##_T1 (DisasContext *ctx) { \
121 if (ctx->memidx) gen_op_st##width##_##reg##_T1_kernel(); \
122 else gen_op_st##width##_##reg##_T1_user();\
123 }
124
125 #endif
126
127 GEN_OP_LD(ub, T0)
128 GEN_OP_LD(b, T0)
129 GEN_OP_ST(b, T0)
130 GEN_OP_LD(uw, T0)
131 GEN_OP_LD(w, T0)
132 GEN_OP_ST(w, T0)
133 GEN_OP_LD(l, T0)
134 GEN_OP_ST(l, T0)
135 GEN_OP_LD(fl, FT0)
136 GEN_OP_ST(fl, FT0)
137 GEN_OP_LD(fq, DT0)
138 GEN_OP_ST(fq, DT0)
139
140 void cpu_dump_state(CPUState * env, FILE * f,
141 int (*cpu_fprintf) (FILE * f, const char *fmt, ...),
142 int flags)
143 {
144 int i;
145 cpu_fprintf(f, "pc=0x%08x sr=0x%08x pr=0x%08x fpscr=0x%08x\n",
146 env->pc, env->sr, env->pr, env->fpscr);
147 cpu_fprintf(f, "spc=0x%08x ssr=0x%08x gbr=0x%08x vbr=0x%08x\n",
148 env->spc, env->ssr, env->gbr, env->vbr);
149 cpu_fprintf(f, "sgr=0x%08x dbr=0x%08x delayed_pc=0x%08x fpul=0x%08x\n",
150 env->sgr, env->dbr, env->delayed_pc, env->fpul);
151 for (i = 0; i < 24; i += 4) {
152 cpu_fprintf(f, "r%d=0x%08x r%d=0x%08x r%d=0x%08x r%d=0x%08x\n",
153 i, env->gregs[i], i + 1, env->gregs[i + 1],
154 i + 2, env->gregs[i + 2], i + 3, env->gregs[i + 3]);
155 }
156 if (env->flags & DELAY_SLOT) {
157 cpu_fprintf(f, "in delay slot (delayed_pc=0x%08x)\n",
158 env->delayed_pc);
159 } else if (env->flags & DELAY_SLOT_CONDITIONAL) {
160 cpu_fprintf(f, "in conditional delay slot (delayed_pc=0x%08x)\n",
161 env->delayed_pc);
162 }
163 }
164
165 void cpu_sh4_reset(CPUSH4State * env)
166 {
167 #if defined(CONFIG_USER_ONLY)
168 env->sr = SR_FD; /* FD - kernel does lazy fpu context switch */
169 #else
170 env->sr = 0x700000F0; /* MD, RB, BL, I3-I0 */
171 #endif
172 env->vbr = 0;
173 env->pc = 0xA0000000;
174 #if defined(CONFIG_USER_ONLY)
175 env->fpscr = FPSCR_PR; /* value for userspace according to the kernel */
176 set_float_rounding_mode(float_round_nearest_even, &env->fp_status); /* ?! */
177 #else
178 env->fpscr = 0x00040001; /* CPU reset value according to SH4 manual */
179 set_float_rounding_mode(float_round_to_zero, &env->fp_status);
180 #endif
181 env->mmucr = 0;
182 }
183
184 CPUSH4State *cpu_sh4_init(const char *cpu_model)
185 {
186 CPUSH4State *env;
187
188 env = qemu_mallocz(sizeof(CPUSH4State));
189 if (!env)
190 return NULL;
191 cpu_exec_init(env);
192 sh4_translate_init();
193 cpu_sh4_reset(env);
194 tlb_flush(env, 1);
195 return env;
196 }
197
198 static void gen_goto_tb(DisasContext * ctx, int n, target_ulong dest)
199 {
200 TranslationBlock *tb;
201 tb = ctx->tb;
202
203 if ((tb->pc & TARGET_PAGE_MASK) == (dest & TARGET_PAGE_MASK) &&
204 !ctx->singlestep_enabled) {
205 /* Use a direct jump if in same page and singlestep not enabled */
206 tcg_gen_goto_tb(n);
207 gen_op_movl_imm_PC(dest);
208 tcg_gen_exit_tb((long) tb + n);
209 } else {
210 gen_op_movl_imm_PC(dest);
211 if (ctx->singlestep_enabled)
212 gen_op_debug();
213 tcg_gen_exit_tb(0);
214 }
215 }
216
217 static void gen_jump(DisasContext * ctx)
218 {
219 if (ctx->delayed_pc == (uint32_t) - 1) {
220 /* Target is not statically known, it comes necessarily from a
221 delayed jump as immediate jump are conditinal jumps */
222 gen_op_movl_delayed_pc_PC();
223 if (ctx->singlestep_enabled)
224 gen_op_debug();
225 tcg_gen_exit_tb(0);
226 } else {
227 gen_goto_tb(ctx, 0, ctx->delayed_pc);
228 }
229 }
230
231 /* Immediate conditional jump (bt or bf) */
232 static void gen_conditional_jump(DisasContext * ctx,
233 target_ulong ift, target_ulong ifnott)
234 {
235 int l1;
236
237 l1 = gen_new_label();
238 gen_op_jT(l1);
239 gen_goto_tb(ctx, 0, ifnott);
240 gen_set_label(l1);
241 gen_goto_tb(ctx, 1, ift);
242 }
243
244 /* Delayed conditional jump (bt or bf) */
245 static void gen_delayed_conditional_jump(DisasContext * ctx)
246 {
247 int l1;
248
249 l1 = gen_new_label();
250 gen_op_jdelayed(l1);
251 gen_goto_tb(ctx, 1, ctx->pc + 2);
252 gen_set_label(l1);
253 gen_jump(ctx);
254 }
255
256 #define B3_0 (ctx->opcode & 0xf)
257 #define B6_4 ((ctx->opcode >> 4) & 0x7)
258 #define B7_4 ((ctx->opcode >> 4) & 0xf)
259 #define B7_0 (ctx->opcode & 0xff)
260 #define B7_0s ((int32_t) (int8_t) (ctx->opcode & 0xff))
261 #define B11_0s (ctx->opcode & 0x800 ? 0xfffff000 | (ctx->opcode & 0xfff) : \
262 (ctx->opcode & 0xfff))
263 #define B11_8 ((ctx->opcode >> 8) & 0xf)
264 #define B15_12 ((ctx->opcode >> 12) & 0xf)
265
266 #define REG(x) ((x) < 8 && (ctx->sr & (SR_MD | SR_RB)) == (SR_MD | SR_RB) ? \
267 (x) + 16 : (x))
268
269 #define ALTREG(x) ((x) < 8 && (ctx->sr & (SR_MD | SR_RB)) != (SR_MD | SR_RB) \
270 ? (x) + 16 : (x))
271
272 #define FREG(x) (ctx->fpscr & FPSCR_FR ? (x) ^ 0x10 : (x))
273 #define XHACK(x) ((((x) & 1 ) << 4) | ((x) & 0xe))
274 #define XREG(x) (ctx->fpscr & FPSCR_FR ? XHACK(x) ^ 0x10 : XHACK(x))
275 #define DREG(x) FREG(x) /* Assumes lsb of (x) is always 0 */
276
277 #define CHECK_NOT_DELAY_SLOT \
278 if (ctx->flags & (DELAY_SLOT | DELAY_SLOT_CONDITIONAL)) \
279 {gen_op_raise_slot_illegal_instruction (); ctx->bstate = BS_EXCP; \
280 return;}
281
282 void _decode_opc(DisasContext * ctx)
283 {
284 #if 0
285 fprintf(stderr, "Translating opcode 0x%04x\n", ctx->opcode);
286 #endif
287 switch (ctx->opcode) {
288 case 0x0019: /* div0u */
289 gen_op_div0u();
290 return;
291 case 0x000b: /* rts */
292 CHECK_NOT_DELAY_SLOT gen_op_rts();
293 ctx->flags |= DELAY_SLOT;
294 ctx->delayed_pc = (uint32_t) - 1;
295 return;
296 case 0x0028: /* clrmac */
297 gen_op_clrmac();
298 return;
299 case 0x0048: /* clrs */
300 gen_op_clrs();
301 return;
302 case 0x0008: /* clrt */
303 gen_op_clrt();
304 return;
305 case 0x0038: /* ldtlb */
306 #if defined(CONFIG_USER_ONLY)
307 assert(0); /* XXXXX */
308 #else
309 gen_op_ldtlb();
310 #endif
311 return;
312 case 0x002b: /* rte */
313 CHECK_NOT_DELAY_SLOT gen_op_rte();
314 ctx->flags |= DELAY_SLOT;
315 ctx->delayed_pc = (uint32_t) - 1;
316 return;
317 case 0x0058: /* sets */
318 gen_op_sets();
319 return;
320 case 0x0018: /* sett */
321 gen_op_sett();
322 return;
323 case 0xfbfd: /* frchg */
324 gen_op_frchg();
325 ctx->bstate = BS_STOP;
326 return;
327 case 0xf3fd: /* fschg */
328 gen_op_fschg();
329 ctx->bstate = BS_STOP;
330 return;
331 case 0x0009: /* nop */
332 return;
333 case 0x001b: /* sleep */
334 if (ctx->memidx) {
335 gen_op_sleep();
336 } else {
337 gen_op_raise_illegal_instruction();
338 ctx->bstate = BS_EXCP;
339 }
340 return;
341 }
342
343 switch (ctx->opcode & 0xf000) {
344 case 0x1000: /* mov.l Rm,@(disp,Rn) */
345 tcg_gen_mov_i32(cpu_T[0], cpu_gregs[REG(B7_4)]);
346 tcg_gen_mov_i32(cpu_T[1], cpu_gregs[REG(B11_8)]);
347 tcg_gen_addi_i32(cpu_T[1], cpu_T[1], B3_0 * 4);
348 gen_op_stl_T0_T1(ctx);
349 return;
350 case 0x5000: /* mov.l @(disp,Rm),Rn */
351 tcg_gen_mov_i32(cpu_T[0], cpu_gregs[REG(B7_4)]);
352 tcg_gen_addi_i32(cpu_T[0], cpu_T[0], B3_0 * 4);
353 gen_op_ldl_T0_T0(ctx);
354 tcg_gen_mov_i32(cpu_gregs[REG(B11_8)], cpu_T[0]);
355 return;
356 case 0xe000: /* mov #imm,Rn */
357 tcg_gen_movi_i32(cpu_gregs[REG(B11_8)], B7_0s);
358 return;
359 case 0x9000: /* mov.w @(disp,PC),Rn */
360 tcg_gen_movi_i32(cpu_T[0], ctx->pc + 4 + B7_0 * 2);
361 gen_op_ldw_T0_T0(ctx);
362 tcg_gen_mov_i32(cpu_gregs[REG(B11_8)], cpu_T[0]);
363 return;
364 case 0xd000: /* mov.l @(disp,PC),Rn */
365 tcg_gen_movi_i32(cpu_T[0], (ctx->pc + 4 + B7_0 * 4) & ~3);
366 gen_op_ldl_T0_T0(ctx);
367 tcg_gen_mov_i32(cpu_gregs[REG(B11_8)], cpu_T[0]);
368 return;
369 case 0x7000: /* add #imm,Rn */
370 tcg_gen_addi_i32(cpu_gregs[REG(B11_8)], cpu_gregs[REG(B11_8)], B7_0s);
371 return;
372 case 0xa000: /* bra disp */
373 CHECK_NOT_DELAY_SLOT
374 gen_op_bra(ctx->delayed_pc = ctx->pc + 4 + B11_0s * 2);
375 ctx->flags |= DELAY_SLOT;
376 return;
377 case 0xb000: /* bsr disp */
378 CHECK_NOT_DELAY_SLOT
379 gen_op_bsr(ctx->pc + 4, ctx->delayed_pc =
380 ctx->pc + 4 + B11_0s * 2);
381 ctx->flags |= DELAY_SLOT;
382 return;
383 }
384
385 switch (ctx->opcode & 0xf00f) {
386 case 0x6003: /* mov Rm,Rn */
387 tcg_gen_mov_i32(cpu_T[0], cpu_gregs[REG(B7_4)]);
388 tcg_gen_mov_i32(cpu_gregs[REG(B11_8)], cpu_T[0]);
389 return;
390 case 0x2000: /* mov.b Rm,@Rn */
391 tcg_gen_mov_i32(cpu_T[0], cpu_gregs[REG(B7_4)]);
392 tcg_gen_mov_i32(cpu_T[1], cpu_gregs[REG(B11_8)]);
393 gen_op_stb_T0_T1(ctx);
394 return;
395 case 0x2001: /* mov.w Rm,@Rn */
396 tcg_gen_mov_i32(cpu_T[0], cpu_gregs[REG(B7_4)]);
397 tcg_gen_mov_i32(cpu_T[1], cpu_gregs[REG(B11_8)]);
398 gen_op_stw_T0_T1(ctx);
399 return;
400 case 0x2002: /* mov.l Rm,@Rn */
401 tcg_gen_mov_i32(cpu_T[0], cpu_gregs[REG(B7_4)]);
402 tcg_gen_mov_i32(cpu_T[1], cpu_gregs[REG(B11_8)]);
403 gen_op_stl_T0_T1(ctx);
404 return;
405 case 0x6000: /* mov.b @Rm,Rn */
406 tcg_gen_mov_i32(cpu_T[0], cpu_gregs[REG(B7_4)]);
407 gen_op_ldb_T0_T0(ctx);
408 tcg_gen_mov_i32(cpu_gregs[REG(B11_8)], cpu_T[0]);
409 return;
410 case 0x6001: /* mov.w @Rm,Rn */
411 tcg_gen_mov_i32(cpu_T[0], cpu_gregs[REG(B7_4)]);
412 gen_op_ldw_T0_T0(ctx);
413 tcg_gen_mov_i32(cpu_gregs[REG(B11_8)], cpu_T[0]);
414 return;
415 case 0x6002: /* mov.l @Rm,Rn */
416 tcg_gen_mov_i32(cpu_T[0], cpu_gregs[REG(B7_4)]);
417 gen_op_ldl_T0_T0(ctx);
418 tcg_gen_mov_i32(cpu_gregs[REG(B11_8)], cpu_T[0]);
419 return;
420 case 0x2004: /* mov.b Rm,@-Rn */
421 tcg_gen_mov_i32(cpu_T[0], cpu_gregs[REG(B7_4)]);
422 tcg_gen_subi_i32(cpu_gregs[REG(B11_8)],
423 cpu_gregs[REG(B11_8)], 1); /* modify register status */
424 tcg_gen_mov_i32(cpu_T[1], cpu_gregs[REG(B11_8)]);
425 tcg_gen_addi_i32(cpu_gregs[REG(B11_8)],
426 cpu_gregs[REG(B11_8)], 1); /* recover register status */
427 gen_op_stb_T0_T1(ctx); /* might cause re-execution */
428 tcg_gen_subi_i32(cpu_gregs[REG(B11_8)],
429 cpu_gregs[REG(B11_8)], 1); /* modify register status */
430 return;
431 case 0x2005: /* mov.w Rm,@-Rn */
432 tcg_gen_mov_i32(cpu_T[0], cpu_gregs[REG(B7_4)]);
433 tcg_gen_subi_i32(cpu_gregs[REG(B11_8)],
434 cpu_gregs[REG(B11_8)], 2);
435 tcg_gen_mov_i32(cpu_T[1], cpu_gregs[REG(B11_8)]);
436 tcg_gen_addi_i32(cpu_gregs[REG(B11_8)],
437 cpu_gregs[REG(B11_8)], 2);
438 gen_op_stw_T0_T1(ctx);
439 tcg_gen_subi_i32(cpu_gregs[REG(B11_8)],
440 cpu_gregs[REG(B11_8)], 2);
441 return;
442 case 0x2006: /* mov.l Rm,@-Rn */
443 tcg_gen_mov_i32(cpu_T[0], cpu_gregs[REG(B7_4)]);
444 tcg_gen_subi_i32(cpu_gregs[REG(B11_8)],
445 cpu_gregs[REG(B11_8)], 4);
446 tcg_gen_mov_i32(cpu_T[1], cpu_gregs[REG(B11_8)]);
447 tcg_gen_addi_i32(cpu_gregs[REG(B11_8)],
448 cpu_gregs[REG(B11_8)], 4);
449 gen_op_stl_T0_T1(ctx);
450 tcg_gen_subi_i32(cpu_gregs[REG(B11_8)],
451 cpu_gregs[REG(B11_8)], 4);
452 return;
453 case 0x6004: /* mov.b @Rm+,Rn */
454 tcg_gen_mov_i32(cpu_T[0], cpu_gregs[REG(B7_4)]);
455 gen_op_ldb_T0_T0(ctx);
456 tcg_gen_mov_i32(cpu_gregs[REG(B11_8)], cpu_T[0]);
457 if ( B11_8 != B7_4 )
458 tcg_gen_addi_i32(cpu_gregs[REG(B7_4)],
459 cpu_gregs[REG(B7_4)], 1);
460 return;
461 case 0x6005: /* mov.w @Rm+,Rn */
462 tcg_gen_mov_i32(cpu_T[0], cpu_gregs[REG(B7_4)]);
463 gen_op_ldw_T0_T0(ctx);
464 tcg_gen_mov_i32(cpu_gregs[REG(B11_8)], cpu_T[0]);
465 if ( B11_8 != B7_4 )
466 tcg_gen_addi_i32(cpu_gregs[REG(B7_4)],
467 cpu_gregs[REG(B7_4)], 2);
468 return;
469 case 0x6006: /* mov.l @Rm+,Rn */
470 tcg_gen_mov_i32(cpu_T[0], cpu_gregs[REG(B7_4)]);
471 gen_op_ldl_T0_T0(ctx);
472 tcg_gen_mov_i32(cpu_gregs[REG(B11_8)], cpu_T[0]);
473 if ( B11_8 != B7_4 )
474 tcg_gen_addi_i32(cpu_gregs[REG(B7_4)],
475 cpu_gregs[REG(B7_4)], 4);
476 return;
477 case 0x0004: /* mov.b Rm,@(R0,Rn) */
478 tcg_gen_mov_i32(cpu_T[0], cpu_gregs[REG(B7_4)]);
479 tcg_gen_mov_i32(cpu_T[1], cpu_gregs[REG(B11_8)]);
480 tcg_gen_add_i32(cpu_T[1], cpu_T[1], cpu_gregs[REG(0)]);
481 gen_op_stb_T0_T1(ctx);
482 return;
483 case 0x0005: /* mov.w Rm,@(R0,Rn) */
484 tcg_gen_mov_i32(cpu_T[0], cpu_gregs[REG(B7_4)]);
485 tcg_gen_mov_i32(cpu_T[1], cpu_gregs[REG(B11_8)]);
486 tcg_gen_add_i32(cpu_T[1], cpu_T[1], cpu_gregs[REG(0)]);
487 gen_op_stw_T0_T1(ctx);
488 return;
489 case 0x0006: /* mov.l Rm,@(R0,Rn) */
490 tcg_gen_mov_i32(cpu_T[0], cpu_gregs[REG(B7_4)]);
491 tcg_gen_mov_i32(cpu_T[1], cpu_gregs[REG(B11_8)]);
492 tcg_gen_add_i32(cpu_T[1], cpu_T[1], cpu_gregs[REG(0)]);
493 gen_op_stl_T0_T1(ctx);
494 return;
495 case 0x000c: /* mov.b @(R0,Rm),Rn */
496 tcg_gen_add_i32(cpu_T[0], cpu_gregs[REG(B7_4)], cpu_gregs[REG(0)]);
497 gen_op_ldb_T0_T0(ctx);
498 tcg_gen_mov_i32(cpu_gregs[REG(B11_8)], cpu_T[0]);
499 return;
500 case 0x000d: /* mov.w @(R0,Rm),Rn */
501 tcg_gen_add_i32(cpu_T[0], cpu_gregs[REG(B7_4)], cpu_gregs[REG(0)]);
502 gen_op_ldw_T0_T0(ctx);
503 tcg_gen_mov_i32(cpu_gregs[REG(B11_8)], cpu_T[0]);
504 return;
505 case 0x000e: /* mov.l @(R0,Rm),Rn */
506 tcg_gen_add_i32(cpu_T[0], cpu_gregs[REG(B7_4)], cpu_gregs[REG(0)]);
507 gen_op_ldl_T0_T0(ctx);
508 tcg_gen_mov_i32(cpu_gregs[REG(B11_8)], cpu_T[0]);
509 return;
510 case 0x6008: /* swap.b Rm,Rn */
511 tcg_gen_andi_i32(cpu_gregs[REG(B11_8)], cpu_gregs[REG(B7_4)], 0xffff0000);
512 tcg_gen_andi_i32(cpu_T[0], cpu_gregs[REG(B7_4)], 0xff);
513 tcg_gen_shli_i32(cpu_T[0], cpu_T[0], 8);
514 tcg_gen_or_i32(cpu_gregs[REG(B11_8)], cpu_gregs[REG(B11_8)], cpu_T[0]);
515 tcg_gen_shri_i32(cpu_T[0], cpu_gregs[REG(B7_4)], 8);
516 tcg_gen_andi_i32(cpu_T[0], cpu_T[0], 0xff);
517 tcg_gen_or_i32(cpu_gregs[REG(B11_8)], cpu_gregs[REG(B11_8)], cpu_T[0]);
518 return;
519 case 0x6009: /* swap.w Rm,Rn */
520 tcg_gen_andi_i32(cpu_T[0], cpu_gregs[REG(B7_4)], 0xffff);
521 tcg_gen_shli_i32(cpu_T[0], cpu_T[0], 16);
522 tcg_gen_shri_i32(cpu_T[1], cpu_gregs[REG(B7_4)], 16);
523 tcg_gen_andi_i32(cpu_T[1], cpu_T[1], 0xffff);
524 tcg_gen_or_i32(cpu_gregs[REG(B11_8)], cpu_T[0], cpu_T[1]);
525 return;
526 case 0x200d: /* xtrct Rm,Rn */
527 tcg_gen_andi_i32(cpu_T[0], cpu_gregs[REG(B7_4)], 0xffff);
528 tcg_gen_shli_i32(cpu_T[0], cpu_T[0], 16);
529 tcg_gen_shri_i32(cpu_T[1], cpu_gregs[REG(B11_8)], 16);
530 tcg_gen_andi_i32(cpu_T[1], cpu_T[1], 0xffff);
531 tcg_gen_or_i32(cpu_gregs[REG(B11_8)], cpu_T[0], cpu_T[1]);
532 return;
533 case 0x300c: /* add Rm,Rn */
534 tcg_gen_add_i32(cpu_gregs[REG(B11_8)], cpu_gregs[REG(B11_8)], cpu_gregs[REG(B7_4)]);
535 return;
536 case 0x300e: /* addc Rm,Rn */
537 tcg_gen_mov_i32(cpu_T[0], cpu_gregs[REG(B7_4)]);
538 tcg_gen_mov_i32(cpu_T[1], cpu_gregs[REG(B11_8)]);
539 gen_op_addc_T0_T1();
540 tcg_gen_mov_i32(cpu_gregs[REG(B11_8)], cpu_T[1]);
541 return;
542 case 0x300f: /* addv Rm,Rn */
543 tcg_gen_mov_i32(cpu_T[0], cpu_gregs[REG(B7_4)]);
544 tcg_gen_mov_i32(cpu_T[1], cpu_gregs[REG(B11_8)]);
545 gen_op_addv_T0_T1();
546 tcg_gen_mov_i32(cpu_gregs[REG(B11_8)], cpu_T[1]);
547 return;
548 case 0x2009: /* and Rm,Rn */
549 tcg_gen_and_i32(cpu_gregs[REG(B11_8)], cpu_gregs[REG(B11_8)], cpu_gregs[REG(B7_4)]);
550 return;
551 case 0x3000: /* cmp/eq Rm,Rn */
552 tcg_gen_mov_i32(cpu_T[0], cpu_gregs[REG(B7_4)]);
553 tcg_gen_mov_i32(cpu_T[1], cpu_gregs[REG(B11_8)]);
554 gen_op_cmp_eq_T0_T1();
555 return;
556 case 0x3003: /* cmp/ge Rm,Rn */
557 tcg_gen_mov_i32(cpu_T[0], cpu_gregs[REG(B7_4)]);
558 tcg_gen_mov_i32(cpu_T[1], cpu_gregs[REG(B11_8)]);
559 gen_op_cmp_ge_T0_T1();
560 return;
561 case 0x3007: /* cmp/gt Rm,Rn */
562 tcg_gen_mov_i32(cpu_T[0], cpu_gregs[REG(B7_4)]);
563 tcg_gen_mov_i32(cpu_T[1], cpu_gregs[REG(B11_8)]);
564 gen_op_cmp_gt_T0_T1();
565 return;
566 case 0x3006: /* cmp/hi Rm,Rn */
567 tcg_gen_mov_i32(cpu_T[0], cpu_gregs[REG(B7_4)]);
568 tcg_gen_mov_i32(cpu_T[1], cpu_gregs[REG(B11_8)]);
569 gen_op_cmp_hi_T0_T1();
570 return;
571 case 0x3002: /* cmp/hs Rm,Rn */
572 tcg_gen_mov_i32(cpu_T[0], cpu_gregs[REG(B7_4)]);
573 tcg_gen_mov_i32(cpu_T[1], cpu_gregs[REG(B11_8)]);
574 gen_op_cmp_hs_T0_T1();
575 return;
576 case 0x200c: /* cmp/str Rm,Rn */
577 tcg_gen_mov_i32(cpu_T[0], cpu_gregs[REG(B7_4)]);
578 tcg_gen_mov_i32(cpu_T[1], cpu_gregs[REG(B11_8)]);
579 gen_op_cmp_str_T0_T1();
580 return;
581 case 0x2007: /* div0s Rm,Rn */
582 tcg_gen_mov_i32(cpu_T[0], cpu_gregs[REG(B7_4)]);
583 tcg_gen_mov_i32(cpu_T[1], cpu_gregs[REG(B11_8)]);
584 gen_op_div0s_T0_T1();
585 return;
586 case 0x3004: /* div1 Rm,Rn */
587 tcg_gen_mov_i32(cpu_T[0], cpu_gregs[REG(B7_4)]);
588 tcg_gen_mov_i32(cpu_T[1], cpu_gregs[REG(B11_8)]);
589 gen_op_div1_T0_T1();
590 tcg_gen_mov_i32(cpu_gregs[REG(B11_8)], cpu_T[1]);
591 return;
592 case 0x300d: /* dmuls.l Rm,Rn */
593 tcg_gen_mov_i32(cpu_T[0], cpu_gregs[REG(B7_4)]);
594 tcg_gen_mov_i32(cpu_T[1], cpu_gregs[REG(B11_8)]);
595 gen_op_dmulsl_T0_T1();
596 return;
597 case 0x3005: /* dmulu.l Rm,Rn */
598 tcg_gen_mov_i32(cpu_T[0], cpu_gregs[REG(B7_4)]);
599 tcg_gen_mov_i32(cpu_T[1], cpu_gregs[REG(B11_8)]);
600 gen_op_dmulul_T0_T1();
601 return;
602 case 0x600e: /* exts.b Rm,Rn */
603 tcg_gen_mov_i32(cpu_T[0], cpu_gregs[REG(B7_4)]);
604 tcg_gen_andi_i32(cpu_T[0], cpu_T[0], 0xff);
605 tcg_gen_ext8s_i32(cpu_T[0], cpu_T[0]);
606 tcg_gen_mov_i32(cpu_gregs[REG(B11_8)], cpu_T[0]);
607 return;
608 case 0x600f: /* exts.w Rm,Rn */
609 tcg_gen_mov_i32(cpu_T[0], cpu_gregs[REG(B7_4)]);
610 tcg_gen_andi_i32(cpu_T[0], cpu_T[0], 0xffff);
611 tcg_gen_ext16s_i32(cpu_T[0], cpu_T[0]);
612 tcg_gen_mov_i32(cpu_gregs[REG(B11_8)], cpu_T[0]);
613 return;
614 case 0x600c: /* extu.b Rm,Rn */
615 tcg_gen_mov_i32(cpu_T[0], cpu_gregs[REG(B7_4)]);
616 tcg_gen_andi_i32(cpu_T[0], cpu_T[0], 0xff);
617 tcg_gen_mov_i32(cpu_gregs[REG(B11_8)], cpu_T[0]);
618 return;
619 case 0x600d: /* extu.w Rm,Rn */
620 tcg_gen_mov_i32(cpu_T[0], cpu_gregs[REG(B7_4)]);
621 tcg_gen_andi_i32(cpu_T[0], cpu_T[0], 0xffff);
622 tcg_gen_mov_i32(cpu_gregs[REG(B11_8)], cpu_T[0]);
623 return;
624 case 0x000f: /* mac.l @Rm+,@Rn+ */
625 tcg_gen_mov_i32(cpu_T[0], cpu_gregs[REG(B11_8)]);
626 gen_op_ldl_T0_T0(ctx);
627 tcg_gen_mov_i32(cpu_T[1], cpu_T[0]);
628 tcg_gen_mov_i32(cpu_T[0], cpu_gregs[REG(B7_4)]);
629 gen_op_ldl_T0_T0(ctx);
630 gen_op_macl_T0_T1();
631 tcg_gen_addi_i32(cpu_gregs[REG(B7_4)], cpu_gregs[REG(B7_4)], 4);
632 tcg_gen_addi_i32(cpu_gregs[REG(B11_8)], cpu_gregs[REG(B11_8)], 4);
633 return;
634 case 0x400f: /* mac.w @Rm+,@Rn+ */
635 tcg_gen_mov_i32(cpu_T[0], cpu_gregs[REG(B11_8)]);
636 gen_op_ldl_T0_T0(ctx);
637 tcg_gen_mov_i32(cpu_T[1], cpu_T[0]);
638 tcg_gen_mov_i32(cpu_T[0], cpu_gregs[REG(B7_4)]);
639 gen_op_ldl_T0_T0(ctx);
640 gen_op_macw_T0_T1();
641 tcg_gen_addi_i32(cpu_gregs[REG(B11_8)], cpu_gregs[REG(B11_8)], 2);
642 tcg_gen_addi_i32(cpu_gregs[REG(B7_4)], cpu_gregs[REG(B7_4)], 2);
643 return;
644 case 0x0007: /* mul.l Rm,Rn */
645 tcg_gen_mov_i32(cpu_T[0], cpu_gregs[REG(B7_4)]);
646 tcg_gen_mov_i32(cpu_T[1], cpu_gregs[REG(B11_8)]);
647 gen_op_mull_T0_T1();
648 return;
649 case 0x200f: /* muls.w Rm,Rn */
650 tcg_gen_mov_i32(cpu_T[0], cpu_gregs[REG(B7_4)]);
651 tcg_gen_andi_i32(cpu_T[0], cpu_T[0], 0xffff);
652 tcg_gen_ext16s_i32(cpu_T[0], cpu_T[0]);
653 tcg_gen_mov_i32(cpu_T[1], cpu_gregs[REG(B11_8)]);
654 tcg_gen_andi_i32(cpu_T[1], cpu_T[1], 0xffff);
655 tcg_gen_ext16s_i32(cpu_T[1], cpu_T[1]);
656 gen_op_mulsw_T0_T1();
657 return;
658 case 0x200e: /* mulu.w Rm,Rn */
659 tcg_gen_mov_i32(cpu_T[0], cpu_gregs[REG(B7_4)]);
660 tcg_gen_andi_i32(cpu_T[0], cpu_T[0], 0xffff);
661 tcg_gen_mov_i32(cpu_T[1], cpu_gregs[REG(B11_8)]);
662 tcg_gen_andi_i32(cpu_T[1], cpu_T[1], 0xffff);
663 gen_op_muluw_T0_T1();
664 return;
665 case 0x600b: /* neg Rm,Rn */
666 tcg_gen_neg_i32(cpu_gregs[REG(B11_8)], cpu_gregs[REG(B7_4)]);
667 return;
668 case 0x600a: /* negc Rm,Rn */
669 tcg_gen_mov_i32(cpu_T[0], cpu_gregs[REG(B7_4)]);
670 gen_op_negc_T0();
671 tcg_gen_mov_i32(cpu_gregs[REG(B11_8)], cpu_T[0]);
672 return;
673 case 0x6007: /* not Rm,Rn */
674 tcg_gen_not_i32(cpu_gregs[REG(B11_8)], cpu_gregs[REG(B7_4)]);
675 return;
676 case 0x200b: /* or Rm,Rn */
677 tcg_gen_or_i32(cpu_gregs[REG(B11_8)], cpu_gregs[REG(B11_8)], cpu_gregs[REG(B7_4)]);
678 return;
679 case 0x400c: /* shad Rm,Rn */
680 tcg_gen_mov_i32(cpu_T[0], cpu_gregs[REG(B7_4)]);
681 tcg_gen_mov_i32(cpu_T[1], cpu_gregs[REG(B11_8)]);
682 gen_op_shad_T0_T1();
683 tcg_gen_mov_i32(cpu_gregs[REG(B11_8)], cpu_T[1]);
684 return;
685 case 0x400d: /* shld Rm,Rn */
686 tcg_gen_mov_i32(cpu_T[0], cpu_gregs[REG(B7_4)]);
687 tcg_gen_mov_i32(cpu_T[1], cpu_gregs[REG(B11_8)]);
688 gen_op_shld_T0_T1();
689 tcg_gen_mov_i32(cpu_gregs[REG(B11_8)], cpu_T[1]);
690 return;
691 case 0x3008: /* sub Rm,Rn */
692 tcg_gen_sub_i32(cpu_gregs[REG(B11_8)], cpu_gregs[REG(B11_8)], cpu_gregs[REG(B7_4)]);
693 return;
694 case 0x300a: /* subc Rm,Rn */
695 tcg_gen_mov_i32(cpu_T[0], cpu_gregs[REG(B7_4)]);
696 tcg_gen_mov_i32(cpu_T[1], cpu_gregs[REG(B11_8)]);
697 gen_op_subc_T0_T1();
698 tcg_gen_mov_i32(cpu_gregs[REG(B11_8)], cpu_T[1]);
699 return;
700 case 0x300b: /* subv Rm,Rn */
701 tcg_gen_mov_i32(cpu_T[0], cpu_gregs[REG(B7_4)]);
702 tcg_gen_mov_i32(cpu_T[1], cpu_gregs[REG(B11_8)]);
703 gen_op_subv_T0_T1();
704 tcg_gen_mov_i32(cpu_gregs[REG(B11_8)], cpu_T[1]);
705 return;
706 case 0x2008: /* tst Rm,Rn */
707 tcg_gen_mov_i32(cpu_T[0], cpu_gregs[REG(B7_4)]);
708 tcg_gen_mov_i32(cpu_T[1], cpu_gregs[REG(B11_8)]);
709 gen_op_tst_T0_T1();
710 return;
711 case 0x200a: /* xor Rm,Rn */
712 tcg_gen_xor_i32(cpu_gregs[REG(B11_8)], cpu_gregs[REG(B11_8)], cpu_gregs[REG(B7_4)]);
713 return;
714 case 0xf00c: /* fmov {F,D,X}Rm,{F,D,X}Rn - FPSCR: Nothing */
715 if (ctx->fpscr & FPSCR_SZ) {
716 gen_op_fmov_drN_DT0(XREG(B7_4));
717 gen_op_fmov_DT0_drN(XREG(B11_8));
718 } else {
719 gen_op_fmov_frN_FT0(FREG(B7_4));
720 gen_op_fmov_FT0_frN(FREG(B11_8));
721 }
722 return;
723 case 0xf00a: /* fmov {F,D,X}Rm,@Rn - FPSCR: Nothing */
724 if (ctx->fpscr & FPSCR_SZ) {
725 gen_op_fmov_drN_DT0(XREG(B7_4));
726 tcg_gen_mov_i32(cpu_T[1], cpu_gregs[REG(B11_8)]);
727 gen_op_stfq_DT0_T1(ctx);
728 } else {
729 gen_op_fmov_frN_FT0(FREG(B7_4));
730 tcg_gen_mov_i32(cpu_T[1], cpu_gregs[REG(B11_8)]);
731 gen_op_stfl_FT0_T1(ctx);
732 }
733 return;
734 case 0xf008: /* fmov @Rm,{F,D,X}Rn - FPSCR: Nothing */
735 if (ctx->fpscr & FPSCR_SZ) {
736 tcg_gen_mov_i32(cpu_T[0], cpu_gregs[REG(B7_4)]);
737 gen_op_ldfq_T0_DT0(ctx);
738 gen_op_fmov_DT0_drN(XREG(B11_8));
739 } else {
740 tcg_gen_mov_i32(cpu_T[0], cpu_gregs[REG(B7_4)]);
741 gen_op_ldfl_T0_FT0(ctx);
742 gen_op_fmov_FT0_frN(FREG(B11_8));
743 }
744 return;
745 case 0xf009: /* fmov @Rm+,{F,D,X}Rn - FPSCR: Nothing */
746 if (ctx->fpscr & FPSCR_SZ) {
747 tcg_gen_mov_i32(cpu_T[0], cpu_gregs[REG(B7_4)]);
748 gen_op_ldfq_T0_DT0(ctx);
749 gen_op_fmov_DT0_drN(XREG(B11_8));
750 tcg_gen_addi_i32(cpu_gregs[REG(B7_4)],
751 cpu_gregs[REG(B7_4)], 8);
752 } else {
753 tcg_gen_mov_i32(cpu_T[0], cpu_gregs[REG(B7_4)]);
754 gen_op_ldfl_T0_FT0(ctx);
755 gen_op_fmov_FT0_frN(FREG(B11_8));
756 tcg_gen_addi_i32(cpu_gregs[REG(B7_4)],
757 cpu_gregs[REG(B7_4)], 4);
758 }
759 return;
760 case 0xf00b: /* fmov {F,D,X}Rm,@-Rn - FPSCR: Nothing */
761 if (ctx->fpscr & FPSCR_SZ) {
762 tcg_gen_subi_i32(cpu_gregs[REG(B11_8)], cpu_gregs[REG(B11_8)], 8);
763 gen_op_fmov_drN_DT0(XREG(B7_4));
764 tcg_gen_mov_i32(cpu_T[1], cpu_gregs[REG(B11_8)]);
765 tcg_gen_addi_i32(cpu_gregs[REG(B11_8)], cpu_gregs[REG(B11_8)], 8);
766 gen_op_stfq_DT0_T1(ctx);
767 tcg_gen_subi_i32(cpu_gregs[REG(B11_8)], cpu_gregs[REG(B11_8)], 8);
768 } else {
769 tcg_gen_subi_i32(cpu_gregs[REG(B11_8)], cpu_gregs[REG(B11_8)], 4);
770 gen_op_fmov_frN_FT0(FREG(B7_4));
771 tcg_gen_mov_i32(cpu_T[1], cpu_gregs[REG(B11_8)]);
772 tcg_gen_addi_i32(cpu_gregs[REG(B11_8)], cpu_gregs[REG(B11_8)], 4);
773 gen_op_stfl_FT0_T1(ctx);
774 tcg_gen_subi_i32(cpu_gregs[REG(B11_8)], cpu_gregs[REG(B11_8)], 4);
775 }
776 return;
777 case 0xf006: /* fmov @(R0,Rm),{F,D,X}Rm - FPSCR: Nothing */
778 tcg_gen_add_i32(cpu_T[0], cpu_gregs[REG(B7_4)], cpu_gregs[REG(0)]);
779 if (ctx->fpscr & FPSCR_SZ) {
780 gen_op_ldfq_T0_DT0(ctx);
781 gen_op_fmov_DT0_drN(XREG(B11_8));
782 } else {
783 gen_op_ldfl_T0_FT0(ctx);
784 gen_op_fmov_FT0_frN(FREG(B11_8));
785 }
786 return;
787 case 0xf007: /* fmov {F,D,X}Rn,@(R0,Rn) - FPSCR: Nothing */
788 if (ctx->fpscr & FPSCR_SZ) {
789 gen_op_fmov_drN_DT0(XREG(B7_4));
790 tcg_gen_mov_i32(cpu_T[1], cpu_gregs[REG(B11_8)]);
791 tcg_gen_add_i32(cpu_T[1], cpu_T[1], cpu_gregs[REG(0)]);
792 gen_op_stfq_DT0_T1(ctx);
793 } else {
794 gen_op_fmov_frN_FT0(FREG(B7_4));
795 tcg_gen_mov_i32(cpu_T[1], cpu_gregs[REG(B11_8)]);
796 tcg_gen_add_i32(cpu_T[1], cpu_T[1], cpu_gregs[REG(0)]);
797 gen_op_stfl_FT0_T1(ctx);
798 }
799 return;
800 case 0xf000: /* fadd Rm,Rn - FPSCR: R[PR,Enable.O/U/I]/W[Cause,Flag] */
801 case 0xf001: /* fsub Rm,Rn - FPSCR: R[PR,Enable.O/U/I]/W[Cause,Flag] */
802 case 0xf002: /* fmul Rm,Rn - FPSCR: R[PR,Enable.O/U/I]/W[Cause,Flag] */
803 case 0xf003: /* fdiv Rm,Rn - FPSCR: R[PR,Enable.O/U/I]/W[Cause,Flag] */
804 case 0xf004: /* fcmp/eq Rm,Rn - FPSCR: R[PR,Enable.V]/W[Cause,Flag] */
805 case 0xf005: /* fcmp/gt Rm,Rn - FPSCR: R[PR,Enable.V]/W[Cause,Flag] */
806 if (ctx->fpscr & FPSCR_PR) {
807 if (ctx->opcode & 0x0110)
808 break; /* illegal instruction */
809 gen_op_fmov_drN_DT1(DREG(B7_4));
810 gen_op_fmov_drN_DT0(DREG(B11_8));
811 }
812 else {
813 gen_op_fmov_frN_FT1(FREG(B7_4));
814 gen_op_fmov_frN_FT0(FREG(B11_8));
815 }
816
817 switch (ctx->opcode & 0xf00f) {
818 case 0xf000: /* fadd Rm,Rn */
819 ctx->fpscr & FPSCR_PR ? gen_op_fadd_DT() : gen_op_fadd_FT();
820 break;
821 case 0xf001: /* fsub Rm,Rn */
822 ctx->fpscr & FPSCR_PR ? gen_op_fsub_DT() : gen_op_fsub_FT();
823 break;
824 case 0xf002: /* fmul Rm,Rn */
825 ctx->fpscr & FPSCR_PR ? gen_op_fmul_DT() : gen_op_fmul_FT();
826 break;
827 case 0xf003: /* fdiv Rm,Rn */
828 ctx->fpscr & FPSCR_PR ? gen_op_fdiv_DT() : gen_op_fdiv_FT();
829 break;
830 case 0xf004: /* fcmp/eq Rm,Rn */
831 ctx->fpscr & FPSCR_PR ? gen_op_fcmp_eq_DT() : gen_op_fcmp_eq_FT();
832 return;
833 case 0xf005: /* fcmp/gt Rm,Rn */
834 ctx->fpscr & FPSCR_PR ? gen_op_fcmp_gt_DT() : gen_op_fcmp_gt_FT();
835 return;
836 }
837
838 if (ctx->fpscr & FPSCR_PR) {
839 gen_op_fmov_DT0_drN(DREG(B11_8));
840 }
841 else {
842 gen_op_fmov_FT0_frN(FREG(B11_8));
843 }
844 return;
845 }
846
847 switch (ctx->opcode & 0xff00) {
848 case 0xc900: /* and #imm,R0 */
849 tcg_gen_andi_i32(cpu_gregs[REG(0)], cpu_gregs[REG(0)], B7_0);
850 return;
851 case 0xcd00: /* and.b #imm,@(R0,GBR) */
852 tcg_gen_mov_i32(cpu_T[0], cpu_gregs[REG(0)]);
853 gen_op_addl_GBR_T0();
854 tcg_gen_mov_i32(cpu_T[1], cpu_T[0]);
855 gen_op_ldub_T0_T0(ctx);
856 tcg_gen_andi_i32(cpu_T[0], cpu_T[0], B7_0);
857 gen_op_stb_T0_T1(ctx);
858 return;
859 case 0x8b00: /* bf label */
860 CHECK_NOT_DELAY_SLOT
861 gen_conditional_jump(ctx, ctx->pc + 2,
862 ctx->pc + 4 + B7_0s * 2);
863 ctx->bstate = BS_BRANCH;
864 return;
865 case 0x8f00: /* bf/s label */
866 CHECK_NOT_DELAY_SLOT
867 gen_op_bf_s(ctx->delayed_pc = ctx->pc + 4 + B7_0s * 2);
868 ctx->flags |= DELAY_SLOT_CONDITIONAL;
869 return;
870 case 0x8900: /* bt label */
871 CHECK_NOT_DELAY_SLOT
872 gen_conditional_jump(ctx, ctx->pc + 4 + B7_0s * 2,
873 ctx->pc + 2);
874 ctx->bstate = BS_BRANCH;
875 return;
876 case 0x8d00: /* bt/s label */
877 CHECK_NOT_DELAY_SLOT
878 gen_op_bt_s(ctx->delayed_pc = ctx->pc + 4 + B7_0s * 2);
879 ctx->flags |= DELAY_SLOT_CONDITIONAL;
880 return;
881 case 0x8800: /* cmp/eq #imm,R0 */
882 tcg_gen_mov_i32(cpu_T[0], cpu_gregs[REG(0)]);
883 gen_op_cmp_eq_imm_T0(B7_0s);
884 return;
885 case 0xc400: /* mov.b @(disp,GBR),R0 */
886 gen_op_stc_gbr_T0();
887 tcg_gen_addi_i32(cpu_T[0], cpu_T[0], B7_0);
888 gen_op_ldb_T0_T0(ctx);
889 tcg_gen_mov_i32(cpu_gregs[REG(0)], cpu_T[0]);
890 return;
891 case 0xc500: /* mov.w @(disp,GBR),R0 */
892 gen_op_stc_gbr_T0();
893 tcg_gen_addi_i32(cpu_T[0], cpu_T[0], B7_0 * 2);
894 gen_op_ldw_T0_T0(ctx);
895 tcg_gen_mov_i32(cpu_gregs[REG(0)], cpu_T[0]);
896 return;
897 case 0xc600: /* mov.l @(disp,GBR),R0 */
898 gen_op_stc_gbr_T0();
899 tcg_gen_addi_i32(cpu_T[0], cpu_T[0], B7_0 * 4);
900 gen_op_ldl_T0_T0(ctx);
901 tcg_gen_mov_i32(cpu_gregs[REG(0)], cpu_T[0]);
902 return;
903 case 0xc000: /* mov.b R0,@(disp,GBR) */
904 gen_op_stc_gbr_T0();
905 tcg_gen_addi_i32(cpu_T[0], cpu_T[0], B7_0);
906 tcg_gen_mov_i32(cpu_T[1], cpu_T[0]);
907 tcg_gen_mov_i32(cpu_T[0], cpu_gregs[REG(0)]);
908 gen_op_stb_T0_T1(ctx);
909 return;
910 case 0xc100: /* mov.w R0,@(disp,GBR) */
911 gen_op_stc_gbr_T0();
912 tcg_gen_addi_i32(cpu_T[0], cpu_T[0], B7_0 * 2);
913 tcg_gen_mov_i32(cpu_T[1], cpu_T[0]);
914 tcg_gen_mov_i32(cpu_T[0], cpu_gregs[REG(0)]);
915 gen_op_stw_T0_T1(ctx);
916 return;
917 case 0xc200: /* mov.l R0,@(disp,GBR) */
918 gen_op_stc_gbr_T0();
919 tcg_gen_addi_i32(cpu_T[0], cpu_T[0], B7_0 * 4);
920 tcg_gen_mov_i32(cpu_T[1], cpu_T[0]);
921 tcg_gen_mov_i32(cpu_T[0], cpu_gregs[REG(0)]);
922 gen_op_stl_T0_T1(ctx);
923 return;
924 case 0x8000: /* mov.b R0,@(disp,Rn) */
925 tcg_gen_mov_i32(cpu_T[0], cpu_gregs[REG(0)]);
926 tcg_gen_mov_i32(cpu_T[1], cpu_gregs[REG(B7_4)]);
927 tcg_gen_addi_i32(cpu_T[1], cpu_T[1], B3_0);
928 gen_op_stb_T0_T1(ctx);
929 return;
930 case 0x8100: /* mov.w R0,@(disp,Rn) */
931 tcg_gen_mov_i32(cpu_T[0], cpu_gregs[REG(0)]);
932 tcg_gen_mov_i32(cpu_T[1], cpu_gregs[REG(B7_4)]);
933 tcg_gen_addi_i32(cpu_T[1], cpu_T[1], B3_0 * 2);
934 gen_op_stw_T0_T1(ctx);
935 return;
936 case 0x8400: /* mov.b @(disp,Rn),R0 */
937 tcg_gen_mov_i32(cpu_T[0], cpu_gregs[REG(B7_4)]);
938 tcg_gen_addi_i32(cpu_T[0], cpu_T[0], B3_0);
939 gen_op_ldb_T0_T0(ctx);
940 tcg_gen_mov_i32(cpu_gregs[REG(0)], cpu_T[0]);
941 return;
942 case 0x8500: /* mov.w @(disp,Rn),R0 */
943 tcg_gen_mov_i32(cpu_T[0], cpu_gregs[REG(B7_4)]);
944 tcg_gen_addi_i32(cpu_T[0], cpu_T[0], B3_0 * 2);
945 gen_op_ldw_T0_T0(ctx);
946 tcg_gen_mov_i32(cpu_gregs[REG(0)], cpu_T[0]);
947 return;
948 case 0xc700: /* mova @(disp,PC),R0 */
949 tcg_gen_movi_i32(cpu_gregs[REG(0)],
950 ((ctx->pc & 0xfffffffc) + 4 + B7_0 * 4) & ~3);
951 return;
952 case 0xcb00: /* or #imm,R0 */
953 tcg_gen_ori_i32(cpu_gregs[REG(0)], cpu_gregs[REG(0)], B7_0);
954 return;
955 case 0xcf00: /* or.b #imm,@(R0,GBR) */
956 tcg_gen_mov_i32(cpu_T[0], cpu_gregs[REG(0)]);
957 gen_op_addl_GBR_T0();
958 tcg_gen_mov_i32(cpu_T[0], cpu_T[1]);
959 gen_op_ldub_T0_T0(ctx);
960 tcg_gen_ori_i32(cpu_T[0], cpu_T[0], B7_0);
961 gen_op_stb_T0_T1(ctx);
962 return;
963 case 0xc300: /* trapa #imm */
964 CHECK_NOT_DELAY_SLOT gen_op_movl_imm_PC(ctx->pc);
965 gen_op_trapa(B7_0);
966 ctx->bstate = BS_BRANCH;
967 return;
968 case 0xc800: /* tst #imm,R0 */
969 gen_op_tst_imm_rN(B7_0, REG(0));
970 return;
971 case 0xcc00: /* tst.b #imm,@(R0,GBR) */
972 tcg_gen_mov_i32(cpu_T[0], cpu_gregs[REG(0)]);
973 gen_op_addl_GBR_T0();
974 gen_op_ldub_T0_T0(ctx);
975 gen_op_tst_imm_T0(B7_0);
976 return;
977 case 0xca00: /* xor #imm,R0 */
978 tcg_gen_xori_i32(cpu_gregs[REG(0)], cpu_gregs[REG(0)], B7_0);
979 return;
980 case 0xce00: /* xor.b #imm,@(R0,GBR) */
981 tcg_gen_mov_i32(cpu_T[0], cpu_gregs[REG(0)]);
982 gen_op_addl_GBR_T0();
983 tcg_gen_mov_i32(cpu_T[1], cpu_T[0]);
984 gen_op_ldub_T0_T0(ctx);
985 tcg_gen_xori_i32(cpu_T[0], cpu_T[0], B7_0);
986 gen_op_stb_T0_T1(ctx);
987 return;
988 }
989
990 switch (ctx->opcode & 0xf08f) {
991 case 0x408e: /* ldc Rm,Rn_BANK */
992 tcg_gen_mov_i32(cpu_T[0], cpu_gregs[REG(B11_8)]);
993 tcg_gen_mov_i32(cpu_gregs[ALTREG(B6_4)], cpu_T[0]);
994 return;
995 case 0x4087: /* ldc.l @Rm+,Rn_BANK */
996 tcg_gen_mov_i32(cpu_T[0], cpu_gregs[REG(B11_8)]);
997 gen_op_ldl_T0_T0(ctx);
998 tcg_gen_mov_i32(cpu_gregs[ALTREG(B6_4)], cpu_T[0]);
999 tcg_gen_addi_i32(cpu_gregs[REG(B11_8)], cpu_gregs[REG(B11_8)], 4);
1000 return;
1001 case 0x0082: /* stc Rm_BANK,Rn */
1002 tcg_gen_mov_i32(cpu_T[0], cpu_gregs[ALTREG(B6_4)]);
1003 tcg_gen_mov_i32(cpu_gregs[REG(B11_8)], cpu_T[0]);
1004 return;
1005 case 0x4083: /* stc.l Rm_BANK,@-Rn */
1006 tcg_gen_subi_i32(cpu_gregs[REG(B11_8)], cpu_gregs[REG(B11_8)], 4);
1007 tcg_gen_mov_i32(cpu_T[1], cpu_gregs[REG(B11_8)]);
1008 tcg_gen_mov_i32(cpu_T[0], cpu_gregs[ALTREG(B6_4)]);
1009 tcg_gen_addi_i32(cpu_gregs[REG(B11_8)], cpu_gregs[REG(B11_8)], 4);
1010 gen_op_stl_T0_T1(ctx);
1011 tcg_gen_subi_i32(cpu_gregs[REG(B11_8)], cpu_gregs[REG(B11_8)], 4);
1012 return;
1013 }
1014
1015 switch (ctx->opcode & 0xf0ff) {
1016 case 0x0023: /* braf Rn */
1017 CHECK_NOT_DELAY_SLOT tcg_gen_mov_i32(cpu_T[0], cpu_gregs[REG(B11_8)]);
1018 gen_op_braf_T0(ctx->pc + 4);
1019 ctx->flags |= DELAY_SLOT;
1020 ctx->delayed_pc = (uint32_t) - 1;
1021 return;
1022 case 0x0003: /* bsrf Rn */
1023 CHECK_NOT_DELAY_SLOT tcg_gen_mov_i32(cpu_T[0], cpu_gregs[REG(B11_8)]);
1024 gen_op_bsrf_T0(ctx->pc + 4);
1025 ctx->flags |= DELAY_SLOT;
1026 ctx->delayed_pc = (uint32_t) - 1;
1027 return;
1028 case 0x4015: /* cmp/pl Rn */
1029 tcg_gen_mov_i32(cpu_T[0], cpu_gregs[REG(B11_8)]);
1030 gen_op_cmp_pl_T0();
1031 return;
1032 case 0x4011: /* cmp/pz Rn */
1033 tcg_gen_mov_i32(cpu_T[0], cpu_gregs[REG(B11_8)]);
1034 gen_op_cmp_pz_T0();
1035 return;
1036 case 0x4010: /* dt Rn */
1037 gen_op_dt_rN(REG(B11_8));
1038 return;
1039 case 0x402b: /* jmp @Rn */
1040 CHECK_NOT_DELAY_SLOT tcg_gen_mov_i32(cpu_T[0], cpu_gregs[REG(B11_8)]);
1041 gen_op_jmp_T0();
1042 ctx->flags |= DELAY_SLOT;
1043 ctx->delayed_pc = (uint32_t) - 1;
1044 return;
1045 case 0x400b: /* jsr @Rn */
1046 CHECK_NOT_DELAY_SLOT tcg_gen_mov_i32(cpu_T[0], cpu_gregs[REG(B11_8)]);
1047 gen_op_jsr_T0(ctx->pc + 4);
1048 ctx->flags |= DELAY_SLOT;
1049 ctx->delayed_pc = (uint32_t) - 1;
1050 return;
1051 #define LDST(reg,ldnum,ldpnum,ldop,stnum,stpnum,stop,extrald) \
1052 case ldnum: \
1053 tcg_gen_mov_i32 (cpu_T[0], cpu_gregs[REG(B11_8)]); \
1054 gen_op_##ldop##_T0_##reg (); \
1055 extrald \
1056 return; \
1057 case ldpnum: \
1058 tcg_gen_mov_i32 (cpu_T[0], cpu_gregs[REG(B11_8)]); \
1059 gen_op_ldl_T0_T0 (ctx); \
1060 tcg_gen_addi_i32(cpu_gregs[REG(B11_8)], \
1061 cpu_gregs[REG(B11_8)], 4); \
1062 gen_op_##ldop##_T0_##reg (); \
1063 extrald \
1064 return; \
1065 case stnum: \
1066 gen_op_##stop##_##reg##_T0 (); \
1067 tcg_gen_mov_i32 (cpu_gregs[REG(B11_8)], cpu_T[0]); \
1068 return; \
1069 case stpnum: \
1070 gen_op_##stop##_##reg##_T0 (); \
1071 tcg_gen_subi_i32(cpu_gregs[REG(B11_8)], \
1072 cpu_gregs[REG(B11_8)], 4); \
1073 tcg_gen_mov_i32 (cpu_T[1], cpu_gregs[REG(B11_8)]); \
1074 tcg_gen_addi_i32(cpu_gregs[REG(B11_8)], \
1075 cpu_gregs[REG(B11_8)], 4); \
1076 gen_op_stl_T0_T1 (ctx); \
1077 tcg_gen_subi_i32(cpu_gregs[REG(B11_8)], \
1078 cpu_gregs[REG(B11_8)], 4); \
1079 return;
1080 LDST(sr, 0x400e, 0x4007, ldc, 0x0002, 0x4003, stc, ctx->bstate =
1081 BS_STOP;)
1082 LDST(gbr, 0x401e, 0x4017, ldc, 0x0012, 0x4013, stc,)
1083 LDST(vbr, 0x402e, 0x4027, ldc, 0x0022, 0x4023, stc,)
1084 LDST(ssr, 0x403e, 0x4037, ldc, 0x0032, 0x4033, stc,)
1085 LDST(spc, 0x404e, 0x4047, ldc, 0x0042, 0x4043, stc,)
1086 LDST(dbr, 0x40fa, 0x40f6, ldc, 0x00fa, 0x40f2, stc,)
1087 LDST(mach, 0x400a, 0x4006, lds, 0x000a, 0x4002, sts,)
1088 LDST(macl, 0x401a, 0x4016, lds, 0x001a, 0x4012, sts,)
1089 LDST(pr, 0x402a, 0x4026, lds, 0x002a, 0x4022, sts,)
1090 LDST(fpul, 0x405a, 0x4056, lds, 0x005a, 0x4052, sts,)
1091 LDST(fpscr, 0x406a, 0x4066, lds, 0x006a, 0x4062, sts, ctx->bstate =
1092 BS_STOP;)
1093 case 0x00c3: /* movca.l R0,@Rm */
1094 tcg_gen_mov_i32(cpu_T[0], cpu_gregs[REG(0)]);
1095 tcg_gen_mov_i32(cpu_T[1], cpu_gregs[REG(B11_8)]);
1096 gen_op_stl_T0_T1(ctx);
1097 return;
1098 case 0x0029: /* movt Rn */
1099 gen_op_movt_rN(REG(B11_8));
1100 return;
1101 case 0x0093: /* ocbi @Rn */
1102 tcg_gen_mov_i32(cpu_T[0], cpu_gregs[REG(B11_8)]);
1103 gen_op_ldl_T0_T0(ctx);
1104 return;
1105 case 0x00a3: /* ocbp @Rn */
1106 tcg_gen_mov_i32(cpu_T[0], cpu_gregs[REG(B11_8)]);
1107 gen_op_ldl_T0_T0(ctx);
1108 return;
1109 case 0x00b3: /* ocbwb @Rn */
1110 tcg_gen_mov_i32(cpu_T[0], cpu_gregs[REG(B11_8)]);
1111 gen_op_ldl_T0_T0(ctx);
1112 return;
1113 case 0x0083: /* pref @Rn */
1114 return;
1115 case 0x4024: /* rotcl Rn */
1116 gen_op_rotcl_Rn(REG(B11_8));
1117 return;
1118 case 0x4025: /* rotcr Rn */
1119 gen_op_rotcr_Rn(REG(B11_8));
1120 return;
1121 case 0x4004: /* rotl Rn */
1122 gen_op_rotl_Rn(REG(B11_8));
1123 return;
1124 case 0x4005: /* rotr Rn */
1125 gen_op_rotr_Rn(REG(B11_8));
1126 return;
1127 case 0x4000: /* shll Rn */
1128 case 0x4020: /* shal Rn */
1129 gen_op_shal_Rn(REG(B11_8));
1130 return;
1131 case 0x4021: /* shar Rn */
1132 gen_op_shar_Rn(REG(B11_8));
1133 return;
1134 case 0x4001: /* shlr Rn */
1135 gen_op_shlr_Rn(REG(B11_8));
1136 return;
1137 case 0x4008: /* shll2 Rn */
1138 tcg_gen_shli_i32(cpu_gregs[REG(B11_8)], cpu_gregs[REG(B11_8)], 2);
1139 return;
1140 case 0x4018: /* shll8 Rn */
1141 tcg_gen_shli_i32(cpu_gregs[REG(B11_8)], cpu_gregs[REG(B11_8)], 8);
1142 return;
1143 case 0x4028: /* shll16 Rn */
1144 tcg_gen_shli_i32(cpu_gregs[REG(B11_8)], cpu_gregs[REG(B11_8)], 16);
1145 return;
1146 case 0x4009: /* shlr2 Rn */
1147 tcg_gen_shri_i32(cpu_gregs[REG(B11_8)], cpu_gregs[REG(B11_8)], 2);
1148 return;
1149 case 0x4019: /* shlr8 Rn */
1150 tcg_gen_shri_i32(cpu_gregs[REG(B11_8)], cpu_gregs[REG(B11_8)], 8);
1151 return;
1152 case 0x4029: /* shlr16 Rn */
1153 tcg_gen_shri_i32(cpu_gregs[REG(B11_8)], cpu_gregs[REG(B11_8)], 16);
1154 return;
1155 case 0x401b: /* tas.b @Rn */
1156 tcg_gen_mov_i32(cpu_T[0], cpu_gregs[REG(B11_8)]);
1157 tcg_gen_mov_i32(cpu_T[1], cpu_T[0]);
1158 gen_op_ldub_T0_T0(ctx);
1159 gen_op_cmp_eq_imm_T0(0);
1160 tcg_gen_ori_i32(cpu_T[0], cpu_T[0], 0x80);
1161 gen_op_stb_T0_T1(ctx);
1162 return;
1163 case 0xf00d: /* fsts FPUL,FRn - FPSCR: Nothing */
1164 gen_op_movl_fpul_FT0();
1165 gen_op_fmov_FT0_frN(FREG(B11_8));
1166 return;
1167 case 0xf01d: /* flds FRm,FPUL - FPSCR: Nothing */
1168 gen_op_fmov_frN_FT0(FREG(B11_8));
1169 gen_op_movl_FT0_fpul();
1170 return;
1171 case 0xf02d: /* float FPUL,FRn/DRn - FPSCR: R[PR,Enable.I]/W[Cause,Flag] */
1172 if (ctx->fpscr & FPSCR_PR) {
1173 if (ctx->opcode & 0x0100)
1174 break; /* illegal instruction */
1175 gen_op_float_DT();
1176 gen_op_fmov_DT0_drN(DREG(B11_8));
1177 }
1178 else {
1179 gen_op_float_FT();
1180 gen_op_fmov_FT0_frN(FREG(B11_8));
1181 }
1182 return;
1183 case 0xf03d: /* ftrc FRm/DRm,FPUL - FPSCR: R[PR,Enable.V]/W[Cause,Flag] */
1184 if (ctx->fpscr & FPSCR_PR) {
1185 if (ctx->opcode & 0x0100)
1186 break; /* illegal instruction */
1187 gen_op_fmov_drN_DT0(DREG(B11_8));
1188 gen_op_ftrc_DT();
1189 }
1190 else {
1191 gen_op_fmov_frN_FT0(FREG(B11_8));
1192 gen_op_ftrc_FT();
1193 }
1194 return;
1195 case 0xf04d: /* fneg FRn/DRn - FPSCR: Nothing */
1196 gen_op_fneg_frN(FREG(B11_8));
1197 return;
1198 case 0xf05d: /* fabs FRn/DRn */
1199 if (ctx->fpscr & FPSCR_PR) {
1200 if (ctx->opcode & 0x0100)
1201 break; /* illegal instruction */
1202 gen_op_fmov_drN_DT0(DREG(B11_8));
1203 gen_op_fabs_DT();
1204 gen_op_fmov_DT0_drN(DREG(B11_8));
1205 } else {
1206 gen_op_fmov_frN_FT0(FREG(B11_8));
1207 gen_op_fabs_FT();
1208 gen_op_fmov_FT0_frN(FREG(B11_8));
1209 }
1210 return;
1211 case 0xf06d: /* fsqrt FRn */
1212 if (ctx->fpscr & FPSCR_PR) {
1213 if (ctx->opcode & 0x0100)
1214 break; /* illegal instruction */
1215 gen_op_fmov_drN_DT0(FREG(B11_8));
1216 gen_op_fsqrt_DT();
1217 gen_op_fmov_DT0_drN(FREG(B11_8));
1218 } else {
1219 gen_op_fmov_frN_FT0(FREG(B11_8));
1220 gen_op_fsqrt_FT();
1221 gen_op_fmov_FT0_frN(FREG(B11_8));
1222 }
1223 return;
1224 case 0xf07d: /* fsrra FRn */
1225 break;
1226 case 0xf08d: /* fldi0 FRn - FPSCR: R[PR] */
1227 if (!(ctx->fpscr & FPSCR_PR)) {
1228 tcg_gen_movi_i32(cpu_T[0], 0);
1229 gen_op_fmov_T0_frN(FREG(B11_8));
1230 return;
1231 }
1232 break;
1233 case 0xf09d: /* fldi1 FRn - FPSCR: R[PR] */
1234 if (!(ctx->fpscr & FPSCR_PR)) {
1235 tcg_gen_movi_i32(cpu_T[0], 0x3f800000);
1236 gen_op_fmov_T0_frN(FREG(B11_8));
1237 return;
1238 }
1239 break;
1240 case 0xf0ad: /* fcnvsd FPUL,DRn */
1241 gen_op_movl_fpul_FT0();
1242 gen_op_fcnvsd_FT_DT();
1243 gen_op_fmov_DT0_drN(DREG(B11_8));
1244 return;
1245 case 0xf0bd: /* fcnvds DRn,FPUL */
1246 gen_op_fmov_drN_DT0(DREG(B11_8));
1247 gen_op_fcnvds_DT_FT();
1248 gen_op_movl_FT0_fpul();
1249 return;
1250 }
1251
1252 fprintf(stderr, "unknown instruction 0x%04x at pc 0x%08x\n",
1253 ctx->opcode, ctx->pc);
1254 gen_op_raise_illegal_instruction();
1255 ctx->bstate = BS_EXCP;
1256 }
1257
1258 void decode_opc(DisasContext * ctx)
1259 {
1260 uint32_t old_flags = ctx->flags;
1261
1262 _decode_opc(ctx);
1263
1264 if (old_flags & (DELAY_SLOT | DELAY_SLOT_CONDITIONAL)) {
1265 if (ctx->flags & DELAY_SLOT_CLEARME) {
1266 gen_op_store_flags(0);
1267 } else {
1268 /* go out of the delay slot */
1269 uint32_t new_flags = ctx->flags;
1270 new_flags &= ~(DELAY_SLOT | DELAY_SLOT_CONDITIONAL);
1271 gen_op_store_flags(new_flags);
1272 }
1273 ctx->flags = 0;
1274 ctx->bstate = BS_BRANCH;
1275 if (old_flags & DELAY_SLOT_CONDITIONAL) {
1276 gen_delayed_conditional_jump(ctx);
1277 } else if (old_flags & DELAY_SLOT) {
1278 gen_jump(ctx);
1279 }
1280
1281 }
1282
1283 /* go into a delay slot */
1284 if (ctx->flags & (DELAY_SLOT | DELAY_SLOT_CONDITIONAL))
1285 gen_op_store_flags(ctx->flags);
1286 }
1287
1288 static inline void
1289 gen_intermediate_code_internal(CPUState * env, TranslationBlock * tb,
1290 int search_pc)
1291 {
1292 DisasContext ctx;
1293 target_ulong pc_start;
1294 static uint16_t *gen_opc_end;
1295 int i, ii;
1296 int num_insns;
1297 int max_insns;
1298
1299 pc_start = tb->pc;
1300 gen_opc_end = gen_opc_buf + OPC_MAX_SIZE;
1301 ctx.pc = pc_start;
1302 ctx.flags = (uint32_t)tb->flags;
1303 ctx.bstate = BS_NONE;
1304 ctx.sr = env->sr;
1305 ctx.fpscr = env->fpscr;
1306 ctx.memidx = (env->sr & SR_MD) ? 1 : 0;
1307 /* We don't know if the delayed pc came from a dynamic or static branch,
1308 so assume it is a dynamic branch. */
1309 ctx.delayed_pc = -1; /* use delayed pc from env pointer */
1310 ctx.tb = tb;
1311 ctx.singlestep_enabled = env->singlestep_enabled;
1312
1313 #ifdef DEBUG_DISAS
1314 if (loglevel & CPU_LOG_TB_CPU) {
1315 fprintf(logfile,
1316 "------------------------------------------------\n");
1317 cpu_dump_state(env, logfile, fprintf, 0);
1318 }
1319 #endif
1320
1321 ii = -1;
1322 num_insns = 0;
1323 max_insns = tb->cflags & CF_COUNT_MASK;
1324 if (max_insns == 0)
1325 max_insns = CF_COUNT_MASK;
1326 gen_icount_start();
1327 while (ctx.bstate == BS_NONE && gen_opc_ptr < gen_opc_end) {
1328 if (env->nb_breakpoints > 0) {
1329 for (i = 0; i < env->nb_breakpoints; i++) {
1330 if (ctx.pc == env->breakpoints[i]) {
1331 /* We have hit a breakpoint - make sure PC is up-to-date */
1332 gen_op_movl_imm_PC(ctx.pc);
1333 gen_op_debug();
1334 ctx.bstate = BS_EXCP;
1335 break;
1336 }
1337 }
1338 }
1339 if (search_pc) {
1340 i = gen_opc_ptr - gen_opc_buf;
1341 if (ii < i) {
1342 ii++;
1343 while (ii < i)
1344 gen_opc_instr_start[ii++] = 0;
1345 }
1346 gen_opc_pc[ii] = ctx.pc;
1347 gen_opc_hflags[ii] = ctx.flags;
1348 gen_opc_instr_start[ii] = 1;
1349 gen_opc_icount[ii] = num_insns;
1350 }
1351 if (num_insns + 1 == max_insns && (tb->cflags & CF_LAST_IO))
1352 gen_io_start();
1353 #if 0
1354 fprintf(stderr, "Loading opcode at address 0x%08x\n", ctx.pc);
1355 fflush(stderr);
1356 #endif
1357 ctx.opcode = lduw_code(ctx.pc);
1358 decode_opc(&ctx);
1359 num_insns++;
1360 ctx.pc += 2;
1361 if ((ctx.pc & (TARGET_PAGE_SIZE - 1)) == 0)
1362 break;
1363 if (env->singlestep_enabled)
1364 break;
1365 if (num_insns >= max_insns)
1366 break;
1367 #ifdef SH4_SINGLE_STEP
1368 break;
1369 #endif
1370 }
1371 if (tb->cflags & CF_LAST_IO)
1372 gen_io_end();
1373 if (env->singlestep_enabled) {
1374 gen_op_debug();
1375 } else {
1376 switch (ctx.bstate) {
1377 case BS_STOP:
1378 /* gen_op_interrupt_restart(); */
1379 /* fall through */
1380 case BS_NONE:
1381 if (ctx.flags) {
1382 gen_op_store_flags(ctx.flags | DELAY_SLOT_CLEARME);
1383 }
1384 gen_goto_tb(&ctx, 0, ctx.pc);
1385 break;
1386 case BS_EXCP:
1387 /* gen_op_interrupt_restart(); */
1388 tcg_gen_exit_tb(0);
1389 break;
1390 case BS_BRANCH:
1391 default:
1392 break;
1393 }
1394 }
1395
1396 gen_icount_end(tb, num_insns);
1397 *gen_opc_ptr = INDEX_op_end;
1398 if (search_pc) {
1399 i = gen_opc_ptr - gen_opc_buf;
1400 ii++;
1401 while (ii <= i)
1402 gen_opc_instr_start[ii++] = 0;
1403 } else {
1404 tb->size = ctx.pc - pc_start;
1405 tb->icount = num_insns;
1406 }
1407
1408 #ifdef DEBUG_DISAS
1409 #ifdef SH4_DEBUG_DISAS
1410 if (loglevel & CPU_LOG_TB_IN_ASM)
1411 fprintf(logfile, "\n");
1412 #endif
1413 if (loglevel & CPU_LOG_TB_IN_ASM) {
1414 fprintf(logfile, "IN:\n"); /* , lookup_symbol(pc_start)); */
1415 target_disas(logfile, pc_start, ctx.pc - pc_start, 0);
1416 fprintf(logfile, "\n");
1417 }
1418 #endif
1419 }
1420
1421 void gen_intermediate_code(CPUState * env, struct TranslationBlock *tb)
1422 {
1423 gen_intermediate_code_internal(env, tb, 0);
1424 }
1425
1426 void gen_intermediate_code_pc(CPUState * env, struct TranslationBlock *tb)
1427 {
1428 gen_intermediate_code_internal(env, tb, 1);
1429 }
1430
1431 void gen_pc_load(CPUState *env, TranslationBlock *tb,
1432 unsigned long searched_pc, int pc_pos, void *puc)
1433 {
1434 env->pc = gen_opc_pc[pc_pos];
1435 env->flags = gen_opc_hflags[pc_pos];
1436 }