]> git.proxmox.com Git - qemu.git/blob - target-sh4/translate.c
sh4 fmov et al instructions (amatus)
[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
35 enum {
36 #define DEF(s, n, copy_size) INDEX_op_ ## s,
37 #include "opc.h"
38 #undef DEF
39 NB_OPS,
40 };
41
42 #ifdef USE_DIRECT_JUMP
43 #define TBPARAM(x)
44 #else
45 #define TBPARAM(x) ((long)(x))
46 #endif
47
48 static uint16_t *gen_opc_ptr;
49 static uint32_t *gen_opparam_ptr;
50
51 #include "gen-op.h"
52
53 typedef struct DisasContext {
54 struct TranslationBlock *tb;
55 target_ulong pc;
56 uint32_t sr;
57 uint32_t fpscr;
58 uint16_t opcode;
59 uint32_t flags;
60 int memidx;
61 uint32_t delayed_pc;
62 int singlestep_enabled;
63 } DisasContext;
64
65 #ifdef CONFIG_USER_ONLY
66
67 #define GEN_OP_LD(width, reg) \
68 void gen_op_ld##width##_T0_##reg (DisasContext *ctx) { \
69 gen_op_ld##width##_T0_##reg##_raw(); \
70 }
71 #define GEN_OP_ST(width, reg) \
72 void gen_op_st##width##_##reg##_T1 (DisasContext *ctx) { \
73 gen_op_st##width##_##reg##_T1_raw(); \
74 }
75
76 #else
77
78 #define GEN_OP_LD(width, reg) \
79 void gen_op_ld##width##_T0_##reg (DisasContext *ctx) { \
80 if (ctx->memidx) gen_op_ld##width##_T0_##reg##_kernel(); \
81 else gen_op_ld##width##_T0_##reg##_user();\
82 }
83 #define GEN_OP_ST(width, reg) \
84 void gen_op_st##width##_##reg##_T1 (DisasContext *ctx) { \
85 if (ctx->memidx) gen_op_st##width##_##reg##_T1_kernel(); \
86 else gen_op_st##width##_##reg##_T1_user();\
87 }
88
89 #endif
90
91 GEN_OP_LD(ub, T0)
92 GEN_OP_LD(b, T0)
93 GEN_OP_ST(b, T0)
94 GEN_OP_LD(uw, T0)
95 GEN_OP_LD(w, T0)
96 GEN_OP_ST(w, T0)
97 GEN_OP_LD(l, T0)
98 GEN_OP_ST(l, T0)
99 GEN_OP_LD(fl, FT0)
100 GEN_OP_ST(fl, FT0)
101 GEN_OP_LD(fq, DT0)
102 GEN_OP_ST(fq, DT0)
103
104 void cpu_dump_state(CPUState * env, FILE * f,
105 int (*cpu_fprintf) (FILE * f, const char *fmt, ...),
106 int flags)
107 {
108 int i;
109 cpu_fprintf(f, "pc=0x%08x sr=0x%08x pr=0x%08x fpscr=0x%08x\n",
110 env->pc, env->sr, env->pr, env->fpscr);
111 for (i = 0; i < 24; i += 4) {
112 cpu_fprintf(f, "r%d=0x%08x r%d=0x%08x r%d=0x%08x r%d=0x%08x\n",
113 i, env->gregs[i], i + 1, env->gregs[i + 1],
114 i + 2, env->gregs[i + 2], i + 3, env->gregs[i + 3]);
115 }
116 if (env->flags & DELAY_SLOT) {
117 cpu_fprintf(f, "in delay slot (delayed_pc=0x%08x)\n",
118 env->delayed_pc);
119 } else if (env->flags & DELAY_SLOT_CONDITIONAL) {
120 cpu_fprintf(f, "in conditional delay slot (delayed_pc=0x%08x)\n",
121 env->delayed_pc);
122 }
123 }
124
125 void cpu_sh4_reset(CPUSH4State * env)
126 {
127 env->sr = 0x700000F0; /* MD, RB, BL, I3-I0 */
128 env->vbr = 0;
129 env->pc = 0xA0000000;
130 env->fpscr = 0x00040001;
131 env->mmucr = 0;
132 }
133
134 CPUSH4State *cpu_sh4_init(void)
135 {
136 CPUSH4State *env;
137
138 env = qemu_mallocz(sizeof(CPUSH4State));
139 if (!env)
140 return NULL;
141 cpu_exec_init(env);
142 cpu_sh4_reset(env);
143 tlb_flush(env, 1);
144 return env;
145 }
146
147 #ifdef CONFIG_USER_ONLY
148 target_ulong cpu_get_phys_page_debug(CPUState * env, target_ulong addr)
149 {
150 return addr;
151 }
152 #else
153 target_ulong cpu_get_phys_page_debug(CPUState * env, target_ulong addr)
154 {
155 target_ulong physical;
156 int prot;
157
158 get_physical_address(env, &physical, &prot, addr, PAGE_READ, 0);
159 return physical;
160 }
161 #endif
162
163 static void gen_goto_tb(DisasContext * ctx, int n, target_ulong dest)
164 {
165 TranslationBlock *tb;
166 tb = ctx->tb;
167
168 if ((tb->pc & TARGET_PAGE_MASK) == (dest & TARGET_PAGE_MASK) &&
169 !ctx->singlestep_enabled) {
170 /* Use a direct jump if in same page and singlestep not enabled */
171 if (n == 0)
172 gen_op_goto_tb0(TBPARAM(tb));
173 else
174 gen_op_goto_tb1(TBPARAM(tb));
175 gen_op_movl_imm_T0((long) tb + n);
176 } else {
177 gen_op_movl_imm_T0(0);
178 }
179 gen_op_movl_imm_PC(dest);
180 if (ctx->singlestep_enabled)
181 gen_op_debug();
182 gen_op_exit_tb();
183 }
184
185 /* Jump to pc after an exception */
186 static void gen_jump_exception(DisasContext * ctx)
187 {
188 gen_op_movl_imm_T0(0);
189 if (ctx->singlestep_enabled)
190 gen_op_debug();
191 gen_op_exit_tb();
192 }
193
194 static void gen_jump(DisasContext * ctx)
195 {
196 if (ctx->delayed_pc == (uint32_t) - 1) {
197 /* Target is not statically known, it comes necessarily from a
198 delayed jump as immediate jump are conditinal jumps */
199 gen_op_movl_delayed_pc_PC();
200 gen_op_movl_imm_T0(0);
201 if (ctx->singlestep_enabled)
202 gen_op_debug();
203 gen_op_exit_tb();
204 } else {
205 gen_goto_tb(ctx, 0, ctx->delayed_pc);
206 }
207 }
208
209 /* Immediate conditional jump (bt or bf) */
210 static void gen_conditional_jump(DisasContext * ctx,
211 target_ulong ift, target_ulong ifnott)
212 {
213 int l1;
214
215 l1 = gen_new_label();
216 gen_op_jT(l1);
217 gen_goto_tb(ctx, 0, ifnott);
218 gen_set_label(l1);
219 gen_goto_tb(ctx, 1, ift);
220 }
221
222 /* Delayed conditional jump (bt or bf) */
223 static void gen_delayed_conditional_jump(DisasContext * ctx)
224 {
225 int l1;
226
227 l1 = gen_new_label();
228 gen_op_jTT2(l1);
229 gen_goto_tb(ctx, 0, ctx->pc);
230 gen_set_label(l1);
231 gen_goto_tb(ctx, 1, ctx->delayed_pc);
232 }
233
234 #define B3_0 (ctx->opcode & 0xf)
235 #define B6_4 ((ctx->opcode >> 4) & 0x7)
236 #define B7_4 ((ctx->opcode >> 4) & 0xf)
237 #define B7_0 (ctx->opcode & 0xff)
238 #define B7_0s ((int32_t) (int8_t) (ctx->opcode & 0xff))
239 #define B11_0s (ctx->opcode & 0x800 ? 0xfffff000 | (ctx->opcode & 0xfff) : \
240 (ctx->opcode & 0xfff))
241 #define B11_8 ((ctx->opcode >> 8) & 0xf)
242 #define B15_12 ((ctx->opcode >> 12) & 0xf)
243
244 #define REG(x) ((x) < 8 && (ctx->sr & (SR_MD | SR_RB)) == (SR_MD | SR_RB) ? \
245 (x) + 16 : (x))
246
247 #define ALTREG(x) ((x) < 8 && (ctx->sr & (SR_MD | SR_RB)) != (SR_MD | SR_RB) \
248 ? (x) + 16 : (x))
249
250 #define FREG(x) (ctx->fpscr & FPSCR_FR ? (x) ^ 0x10 : (x))
251 #define XHACK(x) (((x) & 1 ) << 4 | ((x) & 0xe ) << 1)
252 #define XREG(x) (ctx->fpscr & FPSCR_FR ? XHACK(x) ^ 0x10 : XHACK(x))
253
254 #define CHECK_NOT_DELAY_SLOT \
255 if (ctx->flags & (DELAY_SLOT | DELAY_SLOT_CONDITIONAL)) \
256 {gen_op_raise_slot_illegal_instruction (); ctx->flags |= BRANCH_EXCEPTION; \
257 return;}
258
259 void decode_opc(DisasContext * ctx)
260 {
261 #if 0
262 fprintf(stderr, "Translating opcode 0x%04x\n", ctx->opcode);
263 #endif
264 switch (ctx->opcode) {
265 case 0x0019: /* div0u */
266 printf("div0u\n");
267 gen_op_div0u();
268 return;
269 case 0x000b: /* rts */
270 CHECK_NOT_DELAY_SLOT gen_op_rts();
271 ctx->flags |= DELAY_SLOT;
272 ctx->delayed_pc = (uint32_t) - 1;
273 return;
274 case 0x0028: /* clrmac */
275 gen_op_clrmac();
276 return;
277 case 0x0048: /* clrs */
278 gen_op_clrs();
279 return;
280 case 0x0008: /* clrt */
281 gen_op_clrt();
282 return;
283 case 0x0038: /* ldtlb */
284 assert(0); /* XXXXX */
285 return;
286 case 0x004b: /* rte */
287 CHECK_NOT_DELAY_SLOT gen_op_rte();
288 ctx->flags |= DELAY_SLOT;
289 ctx->delayed_pc = (uint32_t) - 1;
290 return;
291 case 0x0058: /* sets */
292 gen_op_sets();
293 return;
294 case 0x0018: /* sett */
295 gen_op_sett();
296 return;
297 case 0xfbfb: /* frchg */
298 gen_op_frchg();
299 ctx->flags |= MODE_CHANGE;
300 return;
301 case 0xf3fb: /* fschg */
302 gen_op_fschg();
303 ctx->flags |= MODE_CHANGE;
304 return;
305 case 0x0009: /* nop */
306 return;
307 case 0x001b: /* sleep */
308 assert(0); /* XXXXX */
309 return;
310 }
311
312 switch (ctx->opcode & 0xf000) {
313 case 0x1000: /* mov.l Rm,@(disp,Rn) */
314 gen_op_movl_rN_T0(REG(B7_4));
315 gen_op_movl_rN_T1(REG(B11_8));
316 gen_op_addl_imm_T1(B3_0 * 4);
317 gen_op_stl_T0_T1(ctx);
318 return;
319 case 0x5000: /* mov.l @(disp,Rm),Rn */
320 gen_op_movl_rN_T0(REG(B7_4));
321 gen_op_addl_imm_T0(B3_0 * 4);
322 gen_op_ldl_T0_T0(ctx);
323 gen_op_movl_T0_rN(REG(B11_8));
324 return;
325 case 0xe000: /* mov.l #imm,Rn */
326 gen_op_movl_imm_rN(B7_0s, REG(B11_8));
327 return;
328 case 0x9000: /* mov.w @(disp,PC),Rn */
329 gen_op_movl_imm_T0(ctx->pc + 4 + B7_0 * 2);
330 gen_op_ldw_T0_T0(ctx);
331 gen_op_movl_T0_rN(REG(B11_8));
332 return;
333 case 0xd000: /* mov.l @(disp,PC),Rn */
334 gen_op_movl_imm_T0((ctx->pc + 4 + B7_0 * 4) & ~3);
335 gen_op_ldl_T0_T0(ctx);
336 gen_op_movl_T0_rN(REG(B11_8));
337 return;
338 case 0x7000: /* add.l #imm,Rn */
339 gen_op_add_imm_rN(B7_0s, REG(B11_8));
340 return;
341 case 0xa000: /* bra disp */
342 CHECK_NOT_DELAY_SLOT
343 gen_op_bra(ctx->delayed_pc = ctx->pc + 4 + B11_0s * 2);
344 ctx->flags |= DELAY_SLOT;
345 return;
346 case 0xb000: /* bsr disp */
347 CHECK_NOT_DELAY_SLOT
348 gen_op_bsr(ctx->pc + 4, ctx->delayed_pc =
349 ctx->pc + 4 + B11_0s * 2);
350 ctx->flags |= DELAY_SLOT;
351 return;
352 }
353
354 switch (ctx->opcode & 0xf00f) {
355 case 0x6003: /* mov Rm,Rn */
356 gen_op_movl_rN_T0(REG(B7_4));
357 gen_op_movl_T0_rN(REG(B11_8));
358 return;
359 case 0x2000: /* mov.b Rm,@Rn */
360 gen_op_movl_rN_T0(REG(B7_4));
361 gen_op_movl_rN_T1(REG(B11_8));
362 gen_op_stb_T0_T1(ctx);
363 return;
364 case 0x2001: /* mov.w Rm,@Rn */
365 gen_op_movl_rN_T0(REG(B7_4));
366 gen_op_movl_rN_T1(REG(B11_8));
367 gen_op_stw_T0_T1(ctx);
368 return;
369 case 0x2002: /* mov.l Rm,@Rn */
370 gen_op_movl_rN_T0(REG(B7_4));
371 gen_op_movl_rN_T1(REG(B11_8));
372 gen_op_stl_T0_T1(ctx);
373 return;
374 case 0x6000: /* mov.b @Rm,Rn */
375 gen_op_movl_rN_T0(REG(B7_4));
376 gen_op_ldb_T0_T0(ctx);
377 gen_op_movl_T0_rN(REG(B11_8));
378 return;
379 case 0x6001: /* mov.w @Rm,Rn */
380 gen_op_movl_rN_T0(REG(B7_4));
381 gen_op_ldw_T0_T0(ctx);
382 gen_op_movl_T0_rN(REG(B11_8));
383 return;
384 case 0x6002: /* mov.l @Rm,Rn */
385 gen_op_movl_rN_T0(REG(B7_4));
386 gen_op_ldl_T0_T0(ctx);
387 gen_op_movl_T0_rN(REG(B11_8));
388 return;
389 case 0x2004: /* mov.b Rm,@-Rn */
390 gen_op_dec1_rN(REG(B11_8));
391 gen_op_movl_rN_T0(REG(B7_4));
392 gen_op_movl_rN_T1(REG(B11_8));
393 gen_op_stb_T0_T1(ctx);
394 return;
395 case 0x2005: /* mov.w Rm,@-Rn */
396 gen_op_dec2_rN(REG(B11_8));
397 gen_op_movl_rN_T0(REG(B7_4));
398 gen_op_movl_rN_T1(REG(B11_8));
399 gen_op_stw_T0_T1(ctx);
400 return;
401 case 0x2006: /* mov.l Rm,@-Rn */
402 gen_op_dec4_rN(REG(B11_8));
403 gen_op_movl_rN_T0(REG(B7_4));
404 gen_op_movl_rN_T1(REG(B11_8));
405 gen_op_stl_T0_T1(ctx);
406 return;
407 case 0x6004: /* mov.b @Rm+,Rn */
408 gen_op_movl_rN_T0(REG(B7_4));
409 gen_op_ldb_T0_T0(ctx);
410 gen_op_movl_T0_rN(REG(B11_8));
411 gen_op_inc1_rN(REG(B7_4));
412 return;
413 case 0x6005: /* mov.w @Rm+,Rn */
414 gen_op_movl_rN_T0(REG(B7_4));
415 gen_op_ldw_T0_T0(ctx);
416 gen_op_movl_T0_rN(REG(B11_8));
417 gen_op_inc2_rN(REG(B7_4));
418 return;
419 case 0x6006: /* mov.l @Rm+,Rn */
420 gen_op_movl_rN_T0(REG(B7_4));
421 gen_op_ldl_T0_T0(ctx);
422 gen_op_movl_T0_rN(REG(B11_8));
423 gen_op_inc4_rN(REG(B7_4));
424 return;
425 case 0x0004: /* mov.b Rm,@(R0,Rn) */
426 gen_op_movl_rN_T0(REG(B7_4));
427 gen_op_movl_rN_T1(REG(B11_8));
428 gen_op_add_rN_T1(REG(0));
429 gen_op_stb_T0_T1(ctx);
430 return;
431 case 0x0005: /* mov.w Rm,@(R0,Rn) */
432 gen_op_movl_rN_T0(REG(B7_4));
433 gen_op_movl_rN_T1(REG(B11_8));
434 gen_op_add_rN_T1(REG(0));
435 gen_op_stw_T0_T1(ctx);
436 return;
437 case 0x0006: /* mov.l Rm,@(R0,Rn) */
438 gen_op_movl_rN_T0(REG(B7_4));
439 gen_op_movl_rN_T1(REG(B11_8));
440 gen_op_add_rN_T1(REG(0));
441 gen_op_stl_T0_T1(ctx);
442 return;
443 case 0x000c: /* mov.b @(R0,Rm),Rn */
444 gen_op_movl_rN_T0(REG(B7_4));
445 gen_op_add_rN_T0(REG(0));
446 gen_op_ldb_T0_T0(ctx);
447 gen_op_movl_T0_rN(REG(B11_8));
448 return;
449 case 0x000d: /* mov.w @(R0,Rm),Rn */
450 gen_op_movl_rN_T0(REG(B7_4));
451 gen_op_add_rN_T0(REG(0));
452 gen_op_ldw_T0_T0(ctx);
453 gen_op_movl_T0_rN(REG(B11_8));
454 return;
455 case 0x000e: /* mov.l @(R0,Rm),Rn */
456 gen_op_movl_rN_T0(REG(B7_4));
457 gen_op_add_rN_T0(REG(0));
458 gen_op_ldl_T0_T0(ctx);
459 gen_op_movl_T0_rN(REG(B11_8));
460 return;
461 case 0x6008: /* swap.b Rm,Rn */
462 gen_op_movl_rN_T0(REG(B7_4));
463 gen_op_swapb_T0();
464 gen_op_movl_T0_rN(REG(B11_8));
465 return;
466 case 0x6009: /* swap.w Rm,Rn */
467 gen_op_movl_rN_T0(REG(B7_4));
468 gen_op_swapw_T0();
469 gen_op_movl_T0_rN(REG(B11_8));
470 return;
471 case 0x200d: /* xtrct Rm,Rn */
472 gen_op_movl_rN_T0(REG(B7_4));
473 gen_op_movl_rN_T1(REG(B11_8));
474 gen_op_xtrct_T0_T1();
475 gen_op_movl_T1_rN(REG(B11_8));
476 return;
477 case 0x300c: /* add Rm,Rn */
478 gen_op_movl_rN_T0(REG(B7_4));
479 gen_op_add_T0_rN(REG(B11_8));
480 return;
481 case 0x300e: /* addc Rm,Rn */
482 gen_op_movl_rN_T0(REG(B7_4));
483 gen_op_movl_rN_T1(REG(B11_8));
484 gen_op_addc_T0_T1();
485 gen_op_movl_T1_rN(REG(B11_8));
486 return;
487 case 0x300f: /* addv Rm,Rn */
488 gen_op_movl_rN_T0(REG(B7_4));
489 gen_op_movl_rN_T1(REG(B11_8));
490 gen_op_addv_T0_T1();
491 gen_op_movl_T1_rN(REG(B11_8));
492 return;
493 case 0x2009: /* and Rm,Rn */
494 gen_op_movl_rN_T0(REG(B7_4));
495 gen_op_and_T0_rN(REG(B11_8));
496 return;
497 case 0x3000: /* cmp/eq Rm,Rn */
498 gen_op_movl_rN_T0(REG(B7_4));
499 gen_op_movl_rN_T1(REG(B11_8));
500 gen_op_cmp_eq_T0_T1();
501 return;
502 case 0x3003: /* cmp/ge Rm,Rn */
503 gen_op_movl_rN_T0(REG(B7_4));
504 gen_op_movl_rN_T1(REG(B11_8));
505 gen_op_cmp_ge_T0_T1();
506 return;
507 case 0x3007: /* cmp/gt Rm,Rn */
508 gen_op_movl_rN_T0(REG(B7_4));
509 gen_op_movl_rN_T1(REG(B11_8));
510 gen_op_cmp_gt_T0_T1();
511 return;
512 case 0x3006: /* cmp/hi Rm,Rn */
513 gen_op_movl_rN_T0(REG(B7_4));
514 gen_op_movl_rN_T1(REG(B11_8));
515 gen_op_cmp_hi_T0_T1();
516 return;
517 case 0x3002: /* cmp/hs Rm,Rn */
518 gen_op_movl_rN_T0(REG(B7_4));
519 gen_op_movl_rN_T1(REG(B11_8));
520 gen_op_cmp_hs_T0_T1();
521 return;
522 case 0x200c: /* cmp/str Rm,Rn */
523 gen_op_movl_rN_T0(REG(B7_4));
524 gen_op_movl_rN_T1(REG(B11_8));
525 gen_op_cmp_str_T0_T1();
526 return;
527 case 0x2007: /* div0s Rm,Rn */
528 printf("div0s\n");
529 gen_op_movl_rN_T0(REG(B7_4));
530 gen_op_movl_rN_T1(REG(B11_8));
531 gen_op_div0s_T0_T1();
532 gen_op_movl_T1_rN(REG(B11_8));
533 return;
534 case 0x3004: /* div1 Rm,Rn */
535 gen_op_movl_rN_T0(REG(B7_4));
536 gen_op_movl_rN_T1(REG(B11_8));
537 gen_op_div1_T0_T1();
538 gen_op_movl_T1_rN(REG(B11_8));
539 return;
540 case 0x300d: /* dmuls.l Rm,Rn */
541 gen_op_movl_rN_T0(REG(B7_4));
542 gen_op_movl_rN_T1(REG(B11_8));
543 gen_op_dmulsl_T0_T1();
544 return;
545 case 0x3005: /* dmulu.l Rm,Rn */
546 gen_op_movl_rN_T0(REG(B7_4));
547 gen_op_movl_rN_T1(REG(B11_8));
548 gen_op_dmulul_T0_T1();
549 return;
550 case 0x600e: /* exts.b Rm,Rn */
551 gen_op_movb_rN_T0(REG(B7_4));
552 gen_op_movl_T0_rN(REG(B11_8));
553 return;
554 case 0x600f: /* exts.w Rm,Rn */
555 gen_op_movw_rN_T0(REG(B7_4));
556 gen_op_movl_T0_rN(REG(B11_8));
557 return;
558 case 0x600c: /* extu.b Rm,Rn */
559 gen_op_movub_rN_T0(REG(B7_4));
560 gen_op_movl_T0_rN(REG(B11_8));
561 return;
562 case 0x600d: /* extu.w Rm,Rn */
563 gen_op_movuw_rN_T0(REG(B7_4));
564 gen_op_movl_T0_rN(REG(B11_8));
565 return;
566 case 0x000f: /* mac.l @Rm+,@Rn- */
567 gen_op_movl_rN_T0(REG(B11_8));
568 gen_op_ldl_T0_T0(ctx);
569 gen_op_movl_T0_T1();
570 gen_op_movl_rN_T1(REG(B7_4));
571 gen_op_ldl_T0_T0(ctx);
572 gen_op_macl_T0_T1();
573 gen_op_inc4_rN(REG(B7_4));
574 gen_op_inc4_rN(REG(B11_8));
575 return;
576 case 0x400f: /* mac.w @Rm+,@Rn+ */
577 gen_op_movl_rN_T0(REG(B11_8));
578 gen_op_ldl_T0_T0(ctx);
579 gen_op_movl_T0_T1();
580 gen_op_movl_rN_T1(REG(B7_4));
581 gen_op_ldl_T0_T0(ctx);
582 gen_op_macw_T0_T1();
583 gen_op_inc2_rN(REG(B7_4));
584 gen_op_inc2_rN(REG(B11_8));
585 return;
586 case 0x0007: /* mul.l Rm,Rn */
587 gen_op_movl_rN_T0(REG(B7_4));
588 gen_op_movl_rN_T1(REG(B11_8));
589 gen_op_mull_T0_T1();
590 return;
591 case 0x200f: /* muls.w Rm,Rn */
592 gen_op_movw_rN_T0(REG(B7_4));
593 gen_op_movw_rN_T1(REG(B11_8));
594 gen_op_mulsw_T0_T1();
595 return;
596 case 0x200e: /* mulu.w Rm,Rn */
597 gen_op_movuw_rN_T0(REG(B7_4));
598 gen_op_movuw_rN_T1(REG(B11_8));
599 gen_op_muluw_T0_T1();
600 return;
601 case 0x600b: /* neg Rm,Rn */
602 gen_op_movl_rN_T0(REG(B7_4));
603 gen_op_neg_T0();
604 gen_op_movl_T0_rN(REG(B11_8));
605 return;
606 case 0x600a: /* negc Rm,Rn */
607 gen_op_movl_rN_T0(REG(B7_4));
608 gen_op_negc_T0();
609 gen_op_movl_T0_rN(REG(B11_8));
610 return;
611 case 0x6007: /* not Rm,Rn */
612 gen_op_movl_rN_T0(REG(B7_4));
613 gen_op_not_T0();
614 gen_op_movl_T0_rN(REG(B11_8));
615 return;
616 case 0x200b: /* or Rm,Rn */
617 gen_op_movl_rN_T0(REG(B7_4));
618 gen_op_or_T0_rN(REG(B11_8));
619 return;
620 case 0x400c: /* shad Rm,Rn */
621 gen_op_movl_rN_T0(REG(B7_4));
622 gen_op_movl_rN_T1(REG(B11_8));
623 gen_op_shad_T0_T1();
624 gen_op_movl_T1_rN(REG(B11_8));
625 return;
626 case 0x400d: /* shld Rm,Rn */
627 gen_op_movl_rN_T0(REG(B7_4));
628 gen_op_movl_rN_T1(REG(B11_8));
629 gen_op_shld_T0_T1();
630 gen_op_movl_T1_rN(REG(B11_8));
631 return;
632 case 0x3008: /* sub Rm,Rn */
633 gen_op_movl_rN_T0(REG(B7_4));
634 gen_op_sub_T0_rN(REG(B11_8));
635 return;
636 case 0x300a: /* subc Rm,Rn */
637 gen_op_movl_rN_T0(REG(B7_4));
638 gen_op_movl_rN_T1(REG(B11_8));
639 gen_op_subc_T0_T1();
640 gen_op_movl_T1_rN(REG(B11_8));
641 return;
642 case 0x300b: /* subv Rm,Rn */
643 gen_op_movl_rN_T0(REG(B7_4));
644 gen_op_movl_rN_T1(REG(B11_8));
645 gen_op_subv_T0_T1();
646 gen_op_movl_T1_rN(REG(B11_8));
647 return;
648 case 0x2008: /* tst Rm,Rn */
649 gen_op_movl_rN_T0(REG(B7_4));
650 gen_op_movl_rN_T1(REG(B11_8));
651 gen_op_tst_T0_T1();
652 return;
653 case 0x200a: /* xor Rm,Rn */
654 gen_op_movl_rN_T0(REG(B7_4));
655 gen_op_xor_T0_rN(REG(B11_8));
656 return;
657 case 0xf00c: /* fmov {F,D,X}Rm,{F,D,X}Rn */
658 if (ctx->fpscr & FPSCR_PR) {
659 gen_op_fmov_drN_DT0(XREG(B7_4));
660 gen_op_fmov_DT0_drN(XREG(B11_8));
661 } else if (ctx->fpscr & FPSCR_SZ) {
662 if (ctx->opcode & 0x0110)
663 break; /* illegal instruction */
664 gen_op_fmov_drN_DT0(XREG(B7_4));
665 gen_op_fmov_DT0_drN(XREG(B11_8));
666 } else {
667 gen_op_fmov_frN_FT0(FREG(B7_4));
668 gen_op_fmov_FT0_frN(FREG(B11_8));
669 }
670 return;
671 case 0xf00a: /* fmov {F,D,X}Rm,@Rn */
672 if (ctx->fpscr & FPSCR_PR) {
673 gen_op_fmov_drN_DT0(XREG(B7_4));
674 gen_op_movl_rN_T1(REG(B11_8));
675 gen_op_stfq_DT0_T1(ctx);
676 } else if (ctx->fpscr & FPSCR_SZ) {
677 if (ctx->opcode & 0x0010)
678 break; /* illegal instruction */
679 gen_op_fmov_drN_DT0(XREG(B7_4));
680 gen_op_movl_rN_T1(REG(B11_8));
681 gen_op_stfq_DT0_T1(ctx);
682 } else {
683 gen_op_fmov_frN_FT0(FREG(B7_4));
684 gen_op_movl_rN_T1(REG(B11_8));
685 gen_op_stfl_FT0_T1(ctx);
686 }
687 return;
688 case 0xf008: /* fmov @Rm,{F,D,X}Rn */
689 if (ctx->fpscr & FPSCR_PR) {
690 gen_op_movl_rN_T0(REG(B7_4));
691 gen_op_ldfq_T0_DT0(ctx);
692 gen_op_fmov_DT0_drN(XREG(B11_8));
693 } else if (ctx->fpscr & FPSCR_SZ) {
694 if (ctx->opcode & 0x0100)
695 break; /* illegal instruction */
696 gen_op_movl_rN_T0(REG(B7_4));
697 gen_op_ldfq_T0_DT0(ctx);
698 gen_op_fmov_DT0_drN(XREG(B11_8));
699 } else {
700 gen_op_movl_rN_T0(REG(B7_4));
701 gen_op_ldfl_T0_FT0(ctx);
702 gen_op_fmov_FT0_frN(XREG(B11_8));
703 }
704 return;
705 case 0xf009: /* fmov @Rm+,{F,D,X}Rn */
706 if (ctx->fpscr & FPSCR_PR) {
707 gen_op_movl_rN_T0(REG(B7_4));
708 gen_op_ldfq_T0_DT0(ctx);
709 gen_op_fmov_DT0_drN(XREG(B11_8));
710 gen_op_inc8_rN(REG(B7_4));
711 } else if (ctx->fpscr & FPSCR_SZ) {
712 if (ctx->opcode & 0x0100)
713 break; /* illegal instruction */
714 gen_op_movl_rN_T0(REG(B7_4));
715 gen_op_ldfq_T0_DT0(ctx);
716 gen_op_fmov_DT0_drN(XREG(B11_8));
717 gen_op_inc8_rN(REG(B7_4));
718 } else {
719 gen_op_movl_rN_T0(REG(B7_4));
720 gen_op_ldfl_T0_FT0(ctx);
721 gen_op_fmov_FT0_frN(XREG(B11_8));
722 gen_op_inc4_rN(REG(B7_4));
723 }
724 return;
725 case 0xf00b: /* fmov {F,D,X}Rm,@-Rn */
726 if (ctx->fpscr & FPSCR_PR) {
727 gen_op_dec8_rN(REG(B11_8));
728 gen_op_fmov_drN_DT0(XREG(B7_4));
729 gen_op_movl_rN_T1(REG(B11_8));
730 gen_op_stfq_DT0_T1(ctx);
731 } else if (ctx->fpscr & FPSCR_SZ) {
732 if (ctx->opcode & 0x0100)
733 break; /* illegal instruction */
734 gen_op_dec8_rN(REG(B11_8));
735 gen_op_fmov_drN_DT0(XREG(B7_4));
736 gen_op_movl_rN_T1(REG(B11_8));
737 gen_op_stfq_DT0_T1(ctx);
738 } else {
739 gen_op_dec4_rN(REG(B11_8));
740 gen_op_fmov_frN_FT0(FREG(B7_4));
741 gen_op_movl_rN_T1(REG(B11_8));
742 gen_op_stfl_FT0_T1(ctx);
743 }
744 return;
745 case 0xf006: /* fmov @(R0,Rm),{F,D,X}Rm */
746 if (ctx->fpscr & FPSCR_PR) {
747 gen_op_movl_rN_T0(REG(B7_4));
748 gen_op_add_rN_T0(REG(0));
749 gen_op_ldfq_T0_DT0(ctx);
750 gen_op_fmov_DT0_drN(XREG(B11_8));
751 } else if (ctx->fpscr & FPSCR_SZ) {
752 if (ctx->opcode & 0x0100)
753 break; /* illegal instruction */
754 gen_op_movl_rN_T0(REG(B7_4));
755 gen_op_add_rN_T0(REG(0));
756 gen_op_ldfq_T0_DT0(ctx);
757 gen_op_fmov_DT0_drN(XREG(B11_8));
758 } else {
759 gen_op_movl_rN_T0(REG(B7_4));
760 gen_op_add_rN_T0(REG(0));
761 gen_op_ldfl_T0_FT0(ctx);
762 gen_op_fmov_FT0_frN(XREG(B11_8));
763 }
764 return;
765 case 0xf007: /* fmov {F,D,X}Rn,@(R0,Rn) */
766 if (ctx->fpscr & FPSCR_PR) {
767 gen_op_fmov_drN_DT0(XREG(B7_4));
768 gen_op_movl_rN_T1(REG(B11_8));
769 gen_op_add_rN_T1(REG(0));
770 gen_op_stfq_DT0_T1(ctx);
771 } else if (ctx->fpscr & FPSCR_SZ) {
772 if (ctx->opcode & 0x0010)
773 break; /* illegal instruction */
774 gen_op_fmov_drN_DT0(XREG(B7_4));
775 gen_op_movl_rN_T1(REG(B11_8));
776 gen_op_add_rN_T1(REG(0));
777 gen_op_stfq_DT0_T1(ctx);
778 } else {
779 gen_op_fmov_frN_FT0(FREG(B7_4));
780 gen_op_movl_rN_T1(REG(B11_8));
781 gen_op_add_rN_T1(REG(0));
782 gen_op_stfl_FT0_T1(ctx);
783 }
784 return;
785 }
786
787 switch (ctx->opcode & 0xff00) {
788 case 0xc900: /* and #imm,R0 */
789 gen_op_and_imm_rN(B7_0, REG(0));
790 return;
791 case 0xcd00: /* and.b #imm,@(R0+GBR) */
792 gen_op_movl_rN_T0(REG(0));
793 gen_op_addl_GBR_T0();
794 gen_op_movl_T0_T1();
795 gen_op_ldb_T0_T0(ctx);
796 gen_op_and_imm_T0(B7_0);
797 gen_op_stb_T0_T1(ctx);
798 return;
799 case 0x8b00: /* bf label */
800 CHECK_NOT_DELAY_SLOT
801 gen_conditional_jump(ctx, ctx->pc + 2,
802 ctx->pc + 4 + B7_0s * 2);
803 ctx->flags |= BRANCH_CONDITIONAL;
804 return;
805 case 0x8f00: /* bf/s label */
806 CHECK_NOT_DELAY_SLOT
807 gen_op_bf_s(ctx->delayed_pc = ctx->pc + 4 + B7_0s * 2);
808 ctx->flags |= DELAY_SLOT_CONDITIONAL;
809 return;
810 case 0x8900: /* bt label */
811 CHECK_NOT_DELAY_SLOT
812 gen_conditional_jump(ctx, ctx->pc + 4 + B7_0s * 2,
813 ctx->pc + 2);
814 ctx->flags |= BRANCH_CONDITIONAL;
815 return;
816 case 0x8d00: /* bt/s label */
817 CHECK_NOT_DELAY_SLOT
818 gen_op_bt_s(ctx->delayed_pc = ctx->pc + 4 + B7_0s * 2);
819 ctx->flags |= DELAY_SLOT_CONDITIONAL;
820 return;
821 case 0x8800: /* cmp/eq #imm,R0 */
822 gen_op_movl_rN_T0(REG(0));
823 gen_op_cmp_eq_imm_T0(B7_0s);
824 return;
825 case 0xc400: /* mov.b @(disp,GBR),R0 */
826 gen_op_stc_gbr_T0();
827 gen_op_addl_imm_T0(B7_0);
828 gen_op_ldb_T0_T0(ctx);
829 gen_op_movl_T0_rN(REG(0));
830 return;
831 case 0xc500: /* mov.w @(disp,GBR),R0 */
832 gen_op_stc_gbr_T0();
833 gen_op_addl_imm_T0(B7_0);
834 gen_op_ldw_T0_T0(ctx);
835 gen_op_movl_T0_rN(REG(0));
836 return;
837 case 0xc600: /* mov.l @(disp,GBR),R0 */
838 gen_op_stc_gbr_T0();
839 gen_op_addl_imm_T0(B7_0);
840 gen_op_ldl_T0_T0(ctx);
841 gen_op_movl_T0_rN(REG(0));
842 return;
843 case 0xc000: /* mov.b R0,@(disp,GBR) */
844 gen_op_stc_gbr_T0();
845 gen_op_addl_imm_T0(B7_0);
846 gen_op_movl_T0_T1();
847 gen_op_movl_rN_T0(REG(0));
848 gen_op_stb_T0_T1(ctx);
849 return;
850 case 0xc100: /* mov.w R0,@(disp,GBR) */
851 gen_op_stc_gbr_T0();
852 gen_op_addl_imm_T0(B7_0);
853 gen_op_movl_T0_T1();
854 gen_op_movl_rN_T0(REG(0));
855 gen_op_stw_T0_T1(ctx);
856 return;
857 case 0xc200: /* mov.l R0,@(disp,GBR) */
858 gen_op_stc_gbr_T0();
859 gen_op_addl_imm_T0(B7_0);
860 gen_op_movl_T0_T1();
861 gen_op_movl_rN_T0(REG(0));
862 gen_op_stl_T0_T1(ctx);
863 return;
864 case 0x8000: /* mov.b R0,@(disp,Rn) */
865 gen_op_movl_rN_T0(REG(0));
866 gen_op_movl_rN_T1(REG(B7_4));
867 gen_op_addl_imm_T1(B3_0);
868 gen_op_stb_T0_T1(ctx);
869 return;
870 case 0x8100: /* mov.w R0,@(disp,Rn) */
871 gen_op_movl_rN_T0(REG(0));
872 gen_op_movl_rN_T1(REG(B7_4));
873 gen_op_addl_imm_T1(B3_0 * 2);
874 gen_op_stw_T0_T1(ctx);
875 return;
876 case 0x8400: /* mov.b @(disp,Rn),R0 */
877 gen_op_movl_rN_T0(REG(0));
878 gen_op_movl_rN_T1(REG(B7_4));
879 gen_op_addl_imm_T1(B3_0);
880 gen_op_stb_T0_T1(ctx);
881 return;
882 case 0x8500: /* mov.w @(disp,Rn),R0 */
883 gen_op_movl_rN_T0(REG(B7_4));
884 gen_op_addl_imm_T0(B3_0 * 2);
885 gen_op_ldw_T0_T0(ctx);
886 gen_op_movl_T0_rN(REG(0));
887 return;
888 case 0xc700: /* mova @(disp,PC),R0 */
889 gen_op_movl_imm_rN(((ctx->pc & 0xfffffffc) + 4 + B7_0 * 4) & ~3,
890 REG(0));
891 return;
892 case 0xcb00: /* or #imm,R0 */
893 gen_op_or_imm_rN(B7_0, REG(0));
894 return;
895 case 0xcf00: /* or.b #imm,@(R0+GBR) */
896 gen_op_movl_rN_T0(REG(0));
897 gen_op_addl_GBR_T0();
898 gen_op_movl_T0_T1();
899 gen_op_ldb_T0_T0(ctx);
900 gen_op_or_imm_T0(B7_0);
901 gen_op_stb_T0_T1(ctx);
902 return;
903 case 0xc300: /* trapa #imm */
904 CHECK_NOT_DELAY_SLOT gen_op_movl_imm_PC(ctx->pc);
905 gen_op_trapa(B7_0);
906 ctx->flags |= BRANCH;
907 return;
908 case 0xc800: /* tst #imm,R0 */
909 gen_op_tst_imm_rN(B7_0, REG(0));
910 return;
911 case 0xcc00: /* tst #imm,@(R0+GBR) */
912 gen_op_movl_rN_T0(REG(0));
913 gen_op_addl_GBR_T0();
914 gen_op_ldb_T0_T0(ctx);
915 gen_op_tst_imm_T0(B7_0);
916 return;
917 case 0xca00: /* xor #imm,R0 */
918 gen_op_xor_imm_rN(B7_0, REG(0));
919 return;
920 case 0xce00: /* xor.b #imm,@(R0+GBR) */
921 gen_op_movl_rN_T0(REG(0));
922 gen_op_addl_GBR_T0();
923 gen_op_movl_T0_T1();
924 gen_op_ldb_T0_T0(ctx);
925 gen_op_xor_imm_T0(B7_0);
926 gen_op_stb_T0_T1(ctx);
927 return;
928 }
929
930 switch (ctx->opcode & 0xf08f) {
931 case 0x408e: /* ldc Rm,Rn_BANK */
932 gen_op_movl_rN_rN(REG(B11_8), ALTREG(B6_4));
933 return;
934 case 0x4087: /* ldc.l @Rm+,Rn_BANK */
935 gen_op_movl_rN_T0(REG(B11_8));
936 gen_op_ldl_T0_T0(ctx);
937 gen_op_movl_T0_rN(ALTREG(B6_4));
938 gen_op_inc4_rN(REG(B11_8));
939 return;
940 case 0x0082: /* stc Rm_BANK,Rn */
941 gen_op_movl_rN_rN(ALTREG(B6_4), REG(B11_8));
942 return;
943 case 0x4083: /* stc.l Rm_BANK,@-Rn */
944 gen_op_dec4_rN(REG(B11_8));
945 gen_op_movl_rN_T1(REG(B11_8));
946 gen_op_movl_rN_T0(ALTREG(B6_4));
947 gen_op_stl_T0_T1(ctx);
948 return;
949 }
950
951 switch (ctx->opcode & 0xf0ff) {
952 case 0x0023: /* braf Rn */
953 CHECK_NOT_DELAY_SLOT gen_op_movl_rN_T0(REG(B11_8));
954 gen_op_braf_T0(ctx->pc + 4);
955 ctx->flags |= DELAY_SLOT;
956 ctx->delayed_pc = (uint32_t) - 1;
957 return;
958 case 0x0003: /* bsrf Rn */
959 CHECK_NOT_DELAY_SLOT gen_op_movl_rN_T0(REG(B11_8));
960 gen_op_bsrf_T0(ctx->pc + 4);
961 ctx->flags |= DELAY_SLOT;
962 ctx->delayed_pc = (uint32_t) - 1;
963 return;
964 case 0x4015: /* cmp/pl Rn */
965 gen_op_movl_rN_T0(REG(B11_8));
966 gen_op_cmp_pl_T0();
967 return;
968 case 0x4011: /* cmp/pz Rn */
969 gen_op_movl_rN_T0(REG(B11_8));
970 gen_op_cmp_pz_T0();
971 return;
972 case 0x4010: /* dt Rn */
973 gen_op_dt_rN(REG(B11_8));
974 return;
975 case 0x402b: /* jmp @Rn */
976 CHECK_NOT_DELAY_SLOT gen_op_movl_rN_T0(REG(B11_8));
977 gen_op_jmp_T0();
978 ctx->flags |= DELAY_SLOT;
979 ctx->delayed_pc = (uint32_t) - 1;
980 return;
981 case 0x400b: /* jsr @Rn */
982 CHECK_NOT_DELAY_SLOT gen_op_movl_rN_T0(REG(B11_8));
983 gen_op_jsr_T0(ctx->pc + 4);
984 ctx->flags |= DELAY_SLOT;
985 ctx->delayed_pc = (uint32_t) - 1;
986 return;
987 #define LDST(reg,ldnum,ldpnum,ldop,stnum,stpnum,stop,extrald) \
988 case ldnum: \
989 gen_op_movl_rN_T0 (REG(B11_8)); \
990 gen_op_##ldop##_T0_##reg (); \
991 extrald \
992 return; \
993 case ldpnum: \
994 gen_op_movl_rN_T0 (REG(B11_8)); \
995 gen_op_ldl_T0_T0 (ctx); \
996 gen_op_inc4_rN (REG(B11_8)); \
997 gen_op_##ldop##_T0_##reg (); \
998 extrald \
999 return; \
1000 case stnum: \
1001 gen_op_##stop##_##reg##_T0 (); \
1002 gen_op_movl_T0_rN (REG(B11_8)); \
1003 return; \
1004 case stpnum: \
1005 gen_op_##stop##_##reg##_T0 (); \
1006 gen_op_dec4_rN (REG(B11_8)); \
1007 gen_op_movl_rN_T1 (REG(B11_8)); \
1008 gen_op_stl_T0_T1 (ctx); \
1009 return;
1010 LDST(sr, 0x400e, 0x4007, ldc, 0x0002, 0x4003, stc, ctx->flags |=
1011 MODE_CHANGE;)
1012 LDST(gbr, 0x401e, 0x4017, ldc, 0x0012, 0x4013, stc,)
1013 LDST(vbr, 0x402e, 0x4027, ldc, 0x0022, 0x4023, stc,)
1014 LDST(ssr, 0x403e, 0x4037, ldc, 0x0032, 0x4033, stc,)
1015 LDST(spc, 0x404e, 0x4047, ldc, 0x0042, 0x4043, stc,)
1016 LDST(dbr, 0x40fa, 0x40f6, ldc, 0x00fa, 0x40f2, stc,)
1017 LDST(mach, 0x400a, 0x4006, lds, 0x000a, 0x4002, sts,)
1018 LDST(macl, 0x401a, 0x4016, lds, 0x001a, 0x4012, sts,)
1019 LDST(pr, 0x402a, 0x4026, lds, 0x002a, 0x4022, sts,)
1020 LDST(fpul, 0x405a, 0x4056, lds, 0x005a, 0x0052, sts,)
1021 LDST(fpscr, 0x406a, 0x4066, lds, 0x006a, 0x0062, sts, ctx->flags |=
1022 MODE_CHANGE;)
1023 case 0x00c3: /* movca.l R0,@Rm */
1024 gen_op_movl_rN_T0(REG(0));
1025 gen_op_movl_rN_T1(REG(B11_8));
1026 gen_op_stl_T0_T1(ctx);
1027 return;
1028 case 0x0029: /* movt Rn */
1029 gen_op_movt_rN(REG(B11_8));
1030 return;
1031 case 0x0093: /* ocbi @Rn */
1032 gen_op_movl_rN_T0(REG(B11_8));
1033 gen_op_ldl_T0_T0(ctx);
1034 return;
1035 case 0x00a2: /* ocbp @Rn */
1036 gen_op_movl_rN_T0(REG(B11_8));
1037 gen_op_ldl_T0_T0(ctx);
1038 return;
1039 case 0x00b3: /* ocbwb @Rn */
1040 gen_op_movl_rN_T0(REG(B11_8));
1041 gen_op_ldl_T0_T0(ctx);
1042 return;
1043 case 0x0083: /* pref @Rn */
1044 return;
1045 case 0x4024: /* rotcl Rn */
1046 gen_op_rotcl_Rn(REG(B11_8));
1047 return;
1048 case 0x4025: /* rotcr Rn */
1049 gen_op_rotcr_Rn(REG(B11_8));
1050 return;
1051 case 0x4004: /* rotl Rn */
1052 gen_op_rotl_Rn(REG(B11_8));
1053 return;
1054 case 0x4005: /* rotr Rn */
1055 gen_op_rotr_Rn(REG(B11_8));
1056 return;
1057 case 0x4000: /* shll Rn */
1058 case 0x4020: /* shal Rn */
1059 gen_op_shal_Rn(REG(B11_8));
1060 return;
1061 case 0x4021: /* shar Rn */
1062 gen_op_shar_Rn(REG(B11_8));
1063 return;
1064 case 0x4001: /* shlr Rn */
1065 gen_op_shlr_Rn(REG(B11_8));
1066 return;
1067 case 0x4008: /* shll2 Rn */
1068 gen_op_shll2_Rn(REG(B11_8));
1069 return;
1070 case 0x4018: /* shll8 Rn */
1071 gen_op_shll8_Rn(REG(B11_8));
1072 return;
1073 case 0x4028: /* shll16 Rn */
1074 gen_op_shll16_Rn(REG(B11_8));
1075 return;
1076 case 0x4009: /* shlr2 Rn */
1077 gen_op_shlr2_Rn(REG(B11_8));
1078 return;
1079 case 0x4019: /* shlr8 Rn */
1080 gen_op_shlr8_Rn(REG(B11_8));
1081 return;
1082 case 0x4029: /* shlr16 Rn */
1083 gen_op_shlr16_Rn(REG(B11_8));
1084 return;
1085 case 0x401b: /* tas.b @Rn */
1086 gen_op_tasb_rN(REG(B11_8));
1087 return;
1088 case 0xf00d: /* fsts FPUL,FRn */
1089 gen_op_movl_fpul_FT0();
1090 gen_op_fmov_FT0_frN(FREG(B11_8));
1091 return;
1092 case 0xf01d: /* flds FRm.FPUL */
1093 gen_op_fmov_frN_FT0(FREG(B11_8));
1094 gen_op_movl_FT0_fpul();
1095 return;
1096 }
1097
1098 fprintf(stderr, "unknown instruction 0x%04x at pc 0x%08x\n",
1099 ctx->opcode, ctx->pc);
1100 gen_op_raise_illegal_instruction();
1101 ctx->flags |= BRANCH_EXCEPTION;
1102 }
1103
1104 int gen_intermediate_code_internal(CPUState * env, TranslationBlock * tb,
1105 int search_pc)
1106 {
1107 DisasContext ctx;
1108 target_ulong pc_start;
1109 static uint16_t *gen_opc_end;
1110 uint32_t old_flags;
1111 int i;
1112
1113 pc_start = tb->pc;
1114 gen_opc_ptr = gen_opc_buf;
1115 gen_opc_end = gen_opc_buf + OPC_MAX_SIZE;
1116 gen_opparam_ptr = gen_opparam_buf;
1117 ctx.pc = pc_start;
1118 ctx.flags = env->flags;
1119 old_flags = 0;
1120 ctx.sr = env->sr;
1121 ctx.fpscr = env->fpscr;
1122 ctx.memidx = (env->sr & SR_MD) ? 1 : 0;
1123 ctx.delayed_pc = env->delayed_pc;
1124 ctx.tb = tb;
1125 ctx.singlestep_enabled = env->singlestep_enabled;
1126 nb_gen_labels = 0;
1127
1128 #ifdef DEBUG_DISAS
1129 if (loglevel & CPU_LOG_TB_CPU) {
1130 fprintf(logfile,
1131 "------------------------------------------------\n");
1132 cpu_dump_state(env, logfile, fprintf, 0);
1133 }
1134 #endif
1135
1136 while ((old_flags & (DELAY_SLOT | DELAY_SLOT_CONDITIONAL)) == 0 &&
1137 (ctx.flags & (BRANCH | BRANCH_CONDITIONAL | MODE_CHANGE |
1138 BRANCH_EXCEPTION)) == 0 &&
1139 gen_opc_ptr < gen_opc_end && ctx.sr == env->sr) {
1140 old_flags = ctx.flags;
1141 if (env->nb_breakpoints > 0) {
1142 for (i = 0; i < env->nb_breakpoints; i++) {
1143 if (ctx.pc == env->breakpoints[i]) {
1144 /* We have hit a breakpoint - make sure PC is up-to-date */
1145 gen_op_movl_imm_PC(ctx.pc);
1146 gen_op_debug();
1147 ctx.flags |= BRANCH_EXCEPTION;
1148 break;
1149 }
1150 }
1151 }
1152 #if 0
1153 fprintf(stderr, "Loading opcode at address 0x%08x\n", ctx.pc);
1154 fflush(stderr);
1155 #endif
1156 ctx.opcode = lduw_code(ctx.pc);
1157 decode_opc(&ctx);
1158 ctx.pc += 2;
1159 if ((ctx.pc & (TARGET_PAGE_SIZE - 1)) == 0)
1160 break;
1161 if (env->singlestep_enabled)
1162 break;
1163 #ifdef SH4_SINGLE_STEP
1164 break;
1165 #endif
1166 }
1167
1168 switch (old_flags & (DELAY_SLOT_CONDITIONAL | DELAY_SLOT)) {
1169 case DELAY_SLOT_CONDITIONAL:
1170 gen_op_clr_delay_slot_conditional();
1171 gen_delayed_conditional_jump(&ctx);
1172 break;
1173 case DELAY_SLOT:
1174 gen_op_clr_delay_slot();
1175 gen_jump(&ctx);
1176 break;
1177 case 0:
1178 if (ctx.flags & BRANCH_EXCEPTION) {
1179 gen_jump_exception(&ctx);
1180 } else if ((ctx.flags & (BRANCH | BRANCH_CONDITIONAL)) == 0) {
1181 gen_goto_tb(&ctx, 0, ctx.pc);
1182 }
1183 break;
1184 default:
1185 /* Both cannot be set at the same time */
1186 assert(0);
1187 }
1188
1189 if (env->singlestep_enabled) {
1190 gen_op_debug();
1191 }
1192 *gen_opc_ptr = INDEX_op_end;
1193 tb->size = ctx.pc - pc_start;
1194
1195 #ifdef DEBUG_DISAS
1196 #ifdef SH4_DEBUG_DISAS
1197 if (loglevel & CPU_LOG_TB_IN_ASM)
1198 fprintf(logfile, "\n");
1199 #endif
1200 if (loglevel & CPU_LOG_TB_IN_ASM) {
1201 fprintf(logfile, "IN:\n"); /* , lookup_symbol(pc_start)); */
1202 target_disas(logfile, pc_start, ctx.pc - pc_start, 0);
1203 fprintf(logfile, "\n");
1204 }
1205 if (loglevel & CPU_LOG_TB_OP) {
1206 fprintf(logfile, "OP:\n");
1207 dump_ops(gen_opc_buf, gen_opparam_buf);
1208 fprintf(logfile, "\n");
1209 }
1210 #endif
1211 return 0;
1212 }
1213
1214 int gen_intermediate_code(CPUState * env, struct TranslationBlock *tb)
1215 {
1216 return gen_intermediate_code_internal(env, tb, 0);
1217 }
1218
1219 int gen_intermediate_code_pc(CPUState * env, struct TranslationBlock *tb)
1220 {
1221 assert(0);
1222 return gen_intermediate_code_internal(env, tb, 1);
1223 }