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