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 "qemu/osdep.h"
23#include "cpu.h"
24#include "disas/disas.h"
25#include "exec/exec-all.h"
26#include "tcg-op.h"
27#include "exec/cpu_ldst.h"
28#include "exec/helper-proto.h"
29#include "exec/helper-gen.h"
30#include "exec/translator.h"
31#include "trace-tcg.h"
32#include "exec/log.h"
33
34
35typedef struct DisasContext {
36 DisasContextBase base;
37
38 uint32_t tbflags;
39 uint32_t envflags;
40 int memidx;
41 int gbank;
42 int fbank;
43 uint32_t delayed_pc;
44 uint32_t features;
45
46 uint16_t opcode;
47
48 bool has_movcal;
49} DisasContext;
50
51#if defined(CONFIG_USER_ONLY)
52#define IS_USER(ctx) 1
53#else
54#define IS_USER(ctx) (!(ctx->tbflags & (1u << SR_MD)))
55#endif
56
57
58
59
60#define DISAS_STOP DISAS_TARGET_0
61
62
63static TCGv cpu_gregs[32];
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;
68static TCGv cpu_lock_addr, cpu_lock_value;
69static TCGv cpu_fregs[32];
70
71
72static TCGv cpu_flags, cpu_delayed_pc, cpu_delayed_cond;
73
74#include "exec/gen-icount.h"
75
76void sh4_translate_init(void)
77{
78 int i;
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 for (i = 0; i < 24; i++) {
98 cpu_gregs[i] = tcg_global_mem_new_i32(cpu_env,
99 offsetof(CPUSH4State, gregs[i]),
100 gregnames[i]);
101 }
102 memcpy(cpu_gregs + 24, cpu_gregs + 8, 8 * sizeof(TCGv));
103
104 cpu_pc = tcg_global_mem_new_i32(cpu_env,
105 offsetof(CPUSH4State, pc), "PC");
106 cpu_sr = tcg_global_mem_new_i32(cpu_env,
107 offsetof(CPUSH4State, sr), "SR");
108 cpu_sr_m = tcg_global_mem_new_i32(cpu_env,
109 offsetof(CPUSH4State, sr_m), "SR_M");
110 cpu_sr_q = tcg_global_mem_new_i32(cpu_env,
111 offsetof(CPUSH4State, sr_q), "SR_Q");
112 cpu_sr_t = tcg_global_mem_new_i32(cpu_env,
113 offsetof(CPUSH4State, sr_t), "SR_T");
114 cpu_ssr = tcg_global_mem_new_i32(cpu_env,
115 offsetof(CPUSH4State, ssr), "SSR");
116 cpu_spc = tcg_global_mem_new_i32(cpu_env,
117 offsetof(CPUSH4State, spc), "SPC");
118 cpu_gbr = tcg_global_mem_new_i32(cpu_env,
119 offsetof(CPUSH4State, gbr), "GBR");
120 cpu_vbr = tcg_global_mem_new_i32(cpu_env,
121 offsetof(CPUSH4State, vbr), "VBR");
122 cpu_sgr = tcg_global_mem_new_i32(cpu_env,
123 offsetof(CPUSH4State, sgr), "SGR");
124 cpu_dbr = tcg_global_mem_new_i32(cpu_env,
125 offsetof(CPUSH4State, dbr), "DBR");
126 cpu_mach = tcg_global_mem_new_i32(cpu_env,
127 offsetof(CPUSH4State, mach), "MACH");
128 cpu_macl = tcg_global_mem_new_i32(cpu_env,
129 offsetof(CPUSH4State, macl), "MACL");
130 cpu_pr = tcg_global_mem_new_i32(cpu_env,
131 offsetof(CPUSH4State, pr), "PR");
132 cpu_fpscr = tcg_global_mem_new_i32(cpu_env,
133 offsetof(CPUSH4State, fpscr), "FPSCR");
134 cpu_fpul = tcg_global_mem_new_i32(cpu_env,
135 offsetof(CPUSH4State, fpul), "FPUL");
136
137 cpu_flags = tcg_global_mem_new_i32(cpu_env,
138 offsetof(CPUSH4State, flags), "_flags_");
139 cpu_delayed_pc = tcg_global_mem_new_i32(cpu_env,
140 offsetof(CPUSH4State, delayed_pc),
141 "_delayed_pc_");
142 cpu_delayed_cond = tcg_global_mem_new_i32(cpu_env,
143 offsetof(CPUSH4State,
144 delayed_cond),
145 "_delayed_cond_");
146 cpu_lock_addr = tcg_global_mem_new_i32(cpu_env,
147 offsetof(CPUSH4State, lock_addr),
148 "_lock_addr_");
149 cpu_lock_value = tcg_global_mem_new_i32(cpu_env,
150 offsetof(CPUSH4State, lock_value),
151 "_lock_value_");
152
153 for (i = 0; i < 32; i++)
154 cpu_fregs[i] = tcg_global_mem_new_i32(cpu_env,
155 offsetof(CPUSH4State, fregs[i]),
156 fregnames[i]);
157}
158
159void superh_cpu_dump_state(CPUState *cs, FILE *f,
160 fprintf_function cpu_fprintf, int flags)
161{
162 SuperHCPU *cpu = SUPERH_CPU(cs);
163 CPUSH4State *env = &cpu->env;
164 int i;
165 cpu_fprintf(f, "pc=0x%08x sr=0x%08x pr=0x%08x fpscr=0x%08x\n",
166 env->pc, cpu_read_sr(env), env->pr, env->fpscr);
167 cpu_fprintf(f, "spc=0x%08x ssr=0x%08x gbr=0x%08x vbr=0x%08x\n",
168 env->spc, env->ssr, env->gbr, env->vbr);
169 cpu_fprintf(f, "sgr=0x%08x dbr=0x%08x delayed_pc=0x%08x fpul=0x%08x\n",
170 env->sgr, env->dbr, env->delayed_pc, env->fpul);
171 for (i = 0; i < 24; i += 4) {
172 cpu_fprintf(f, "r%d=0x%08x r%d=0x%08x r%d=0x%08x r%d=0x%08x\n",
173 i, env->gregs[i], i + 1, env->gregs[i + 1],
174 i + 2, env->gregs[i + 2], i + 3, env->gregs[i + 3]);
175 }
176 if (env->flags & DELAY_SLOT) {
177 cpu_fprintf(f, "in delay slot (delayed_pc=0x%08x)\n",
178 env->delayed_pc);
179 } else if (env->flags & DELAY_SLOT_CONDITIONAL) {
180 cpu_fprintf(f, "in conditional delay slot (delayed_pc=0x%08x)\n",
181 env->delayed_pc);
182 } else if (env->flags & DELAY_SLOT_RTE) {
183 cpu_fprintf(f, "in rte delay slot (delayed_pc=0x%08x)\n",
184 env->delayed_pc);
185 }
186}
187
188static void gen_read_sr(TCGv dst)
189{
190 TCGv t0 = tcg_temp_new();
191 tcg_gen_shli_i32(t0, cpu_sr_q, SR_Q);
192 tcg_gen_or_i32(dst, dst, t0);
193 tcg_gen_shli_i32(t0, cpu_sr_m, SR_M);
194 tcg_gen_or_i32(dst, dst, t0);
195 tcg_gen_shli_i32(t0, cpu_sr_t, SR_T);
196 tcg_gen_or_i32(dst, cpu_sr, t0);
197 tcg_temp_free_i32(t0);
198}
199
200static void gen_write_sr(TCGv src)
201{
202 tcg_gen_andi_i32(cpu_sr, src,
203 ~((1u << SR_Q) | (1u << SR_M) | (1u << SR_T)));
204 tcg_gen_extract_i32(cpu_sr_q, src, SR_Q, 1);
205 tcg_gen_extract_i32(cpu_sr_m, src, SR_M, 1);
206 tcg_gen_extract_i32(cpu_sr_t, src, SR_T, 1);
207}
208
209static inline void gen_save_cpu_state(DisasContext *ctx, bool save_pc)
210{
211 if (save_pc) {
212 tcg_gen_movi_i32(cpu_pc, ctx->base.pc_next);
213 }
214 if (ctx->delayed_pc != (uint32_t) -1) {
215 tcg_gen_movi_i32(cpu_delayed_pc, ctx->delayed_pc);
216 }
217 if ((ctx->tbflags & TB_FLAG_ENVFLAGS_MASK) != ctx->envflags) {
218 tcg_gen_movi_i32(cpu_flags, ctx->envflags);
219 }
220}
221
222static inline bool use_exit_tb(DisasContext *ctx)
223{
224 return (ctx->tbflags & GUSA_EXCLUSIVE) != 0;
225}
226
227static inline bool use_goto_tb(DisasContext *ctx, target_ulong dest)
228{
229
230 if (unlikely(ctx->base.singlestep_enabled || use_exit_tb(ctx))) {
231 return false;
232 }
233#ifndef CONFIG_USER_ONLY
234 return (ctx->base.tb->pc & TARGET_PAGE_MASK) == (dest & TARGET_PAGE_MASK);
235#else
236 return true;
237#endif
238}
239
240static void gen_goto_tb(DisasContext *ctx, int n, target_ulong dest)
241{
242 if (use_goto_tb(ctx, dest)) {
243 tcg_gen_goto_tb(n);
244 tcg_gen_movi_i32(cpu_pc, dest);
245 tcg_gen_exit_tb(ctx->base.tb, n);
246 } else {
247 tcg_gen_movi_i32(cpu_pc, dest);
248 if (ctx->base.singlestep_enabled) {
249 gen_helper_debug(cpu_env);
250 } else if (use_exit_tb(ctx)) {
251 tcg_gen_exit_tb(NULL, 0);
252 } else {
253 tcg_gen_lookup_and_goto_ptr();
254 }
255 }
256 ctx->base.is_jmp = DISAS_NORETURN;
257}
258
259static void gen_jump(DisasContext * ctx)
260{
261 if (ctx->delayed_pc == -1) {
262
263
264 tcg_gen_mov_i32(cpu_pc, cpu_delayed_pc);
265 tcg_gen_discard_i32(cpu_delayed_pc);
266 if (ctx->base.singlestep_enabled) {
267 gen_helper_debug(cpu_env);
268 } else if (use_exit_tb(ctx)) {
269 tcg_gen_exit_tb(NULL, 0);
270 } else {
271 tcg_gen_lookup_and_goto_ptr();
272 }
273 ctx->base.is_jmp = DISAS_NORETURN;
274 } else {
275 gen_goto_tb(ctx, 0, ctx->delayed_pc);
276 }
277}
278
279
280static void gen_conditional_jump(DisasContext *ctx, target_ulong dest,
281 bool jump_if_true)
282{
283 TCGLabel *l1 = gen_new_label();
284 TCGCond cond_not_taken = jump_if_true ? TCG_COND_EQ : TCG_COND_NE;
285
286 if (ctx->tbflags & GUSA_EXCLUSIVE) {
287
288
289
290 tcg_gen_brcondi_i32(cond_not_taken, cpu_sr_t, 0, l1);
291 tcg_gen_movi_i32(cpu_flags, ctx->envflags & ~GUSA_MASK);
292
293
294 gen_goto_tb(ctx, 0, dest);
295 gen_set_label(l1);
296 ctx->base.is_jmp = DISAS_NEXT;
297 return;
298 }
299
300 gen_save_cpu_state(ctx, false);
301 tcg_gen_brcondi_i32(cond_not_taken, cpu_sr_t, 0, l1);
302 gen_goto_tb(ctx, 0, dest);
303 gen_set_label(l1);
304 gen_goto_tb(ctx, 1, ctx->base.pc_next + 2);
305 ctx->base.is_jmp = DISAS_NORETURN;
306}
307
308
309static void gen_delayed_conditional_jump(DisasContext * ctx)
310{
311 TCGLabel *l1 = gen_new_label();
312 TCGv ds = tcg_temp_new();
313
314 tcg_gen_mov_i32(ds, cpu_delayed_cond);
315 tcg_gen_discard_i32(cpu_delayed_cond);
316
317 if (ctx->tbflags & GUSA_EXCLUSIVE) {
318
319
320
321 tcg_gen_brcondi_i32(TCG_COND_EQ, ds, 0, l1);
322
323
324 tcg_gen_movi_i32(cpu_flags, ctx->envflags & ~GUSA_MASK);
325 gen_jump(ctx);
326
327 gen_set_label(l1);
328 ctx->base.is_jmp = DISAS_NEXT;
329 return;
330 }
331
332 tcg_gen_brcondi_i32(TCG_COND_NE, ds, 0, l1);
333 gen_goto_tb(ctx, 1, ctx->base.pc_next + 2);
334 gen_set_label(l1);
335 gen_jump(ctx);
336}
337
338static inline void gen_load_fpr64(DisasContext *ctx, TCGv_i64 t, int reg)
339{
340
341 tcg_debug_assert((reg & 1) == 0);
342 reg ^= ctx->fbank;
343 tcg_gen_concat_i32_i64(t, cpu_fregs[reg + 1], cpu_fregs[reg]);
344}
345
346static inline void gen_store_fpr64(DisasContext *ctx, TCGv_i64 t, int reg)
347{
348
349 tcg_debug_assert((reg & 1) == 0);
350 reg ^= ctx->fbank;
351 tcg_gen_extr_i64_i32(cpu_fregs[reg + 1], cpu_fregs[reg], t);
352}
353
354#define B3_0 (ctx->opcode & 0xf)
355#define B6_4 ((ctx->opcode >> 4) & 0x7)
356#define B7_4 ((ctx->opcode >> 4) & 0xf)
357#define B7_0 (ctx->opcode & 0xff)
358#define B7_0s ((int32_t) (int8_t) (ctx->opcode & 0xff))
359#define B11_0s (ctx->opcode & 0x800 ? 0xfffff000 | (ctx->opcode & 0xfff) : \
360 (ctx->opcode & 0xfff))
361#define B11_8 ((ctx->opcode >> 8) & 0xf)
362#define B15_12 ((ctx->opcode >> 12) & 0xf)
363
364#define REG(x) cpu_gregs[(x) ^ ctx->gbank]
365#define ALTREG(x) cpu_gregs[(x) ^ ctx->gbank ^ 0x10]
366#define FREG(x) cpu_fregs[(x) ^ ctx->fbank]
367
368#define XHACK(x) ((((x) & 1 ) << 4) | ((x) & 0xe))
369
370#define CHECK_NOT_DELAY_SLOT \
371 if (ctx->envflags & DELAY_SLOT_MASK) { \
372 goto do_illegal_slot; \
373 }
374
375#define CHECK_PRIVILEGED \
376 if (IS_USER(ctx)) { \
377 goto do_illegal; \
378 }
379
380#define CHECK_FPU_ENABLED \
381 if (ctx->tbflags & (1u << SR_FD)) { \
382 goto do_fpu_disabled; \
383 }
384
385#define CHECK_FPSCR_PR_0 \
386 if (ctx->tbflags & FPSCR_PR) { \
387 goto do_illegal; \
388 }
389
390#define CHECK_FPSCR_PR_1 \
391 if (!(ctx->tbflags & FPSCR_PR)) { \
392 goto do_illegal; \
393 }
394
395#define CHECK_SH4A \
396 if (!(ctx->features & SH_FEATURE_SH4A)) { \
397 goto do_illegal; \
398 }
399
400static void _decode_opc(DisasContext * ctx)
401{
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422 if (ctx->has_movcal)
423 {
424 int opcode = ctx->opcode & 0xf0ff;
425 if (opcode != 0x0093
426 && opcode != 0x00c3 )
427 {
428 gen_helper_discard_movcal_backup(cpu_env);
429 ctx->has_movcal = 0;
430 }
431 }
432
433#if 0
434 fprintf(stderr, "Translating opcode 0x%04x\n", ctx->opcode);
435#endif
436
437 switch (ctx->opcode) {
438 case 0x0019:
439 tcg_gen_movi_i32(cpu_sr_m, 0);
440 tcg_gen_movi_i32(cpu_sr_q, 0);
441 tcg_gen_movi_i32(cpu_sr_t, 0);
442 return;
443 case 0x000b:
444 CHECK_NOT_DELAY_SLOT
445 tcg_gen_mov_i32(cpu_delayed_pc, cpu_pr);
446 ctx->envflags |= DELAY_SLOT;
447 ctx->delayed_pc = (uint32_t) - 1;
448 return;
449 case 0x0028:
450 tcg_gen_movi_i32(cpu_mach, 0);
451 tcg_gen_movi_i32(cpu_macl, 0);
452 return;
453 case 0x0048:
454 tcg_gen_andi_i32(cpu_sr, cpu_sr, ~(1u << SR_S));
455 return;
456 case 0x0008:
457 tcg_gen_movi_i32(cpu_sr_t, 0);
458 return;
459 case 0x0038:
460 CHECK_PRIVILEGED
461 gen_helper_ldtlb(cpu_env);
462 return;
463 case 0x002b:
464 CHECK_PRIVILEGED
465 CHECK_NOT_DELAY_SLOT
466 gen_write_sr(cpu_ssr);
467 tcg_gen_mov_i32(cpu_delayed_pc, cpu_spc);
468 ctx->envflags |= DELAY_SLOT_RTE;
469 ctx->delayed_pc = (uint32_t) - 1;
470 ctx->base.is_jmp = DISAS_STOP;
471 return;
472 case 0x0058:
473 tcg_gen_ori_i32(cpu_sr, cpu_sr, (1u << SR_S));
474 return;
475 case 0x0018:
476 tcg_gen_movi_i32(cpu_sr_t, 1);
477 return;
478 case 0xfbfd:
479 CHECK_FPSCR_PR_0
480 tcg_gen_xori_i32(cpu_fpscr, cpu_fpscr, FPSCR_FR);
481 ctx->base.is_jmp = DISAS_STOP;
482 return;
483 case 0xf3fd:
484 CHECK_FPSCR_PR_0
485 tcg_gen_xori_i32(cpu_fpscr, cpu_fpscr, FPSCR_SZ);
486 ctx->base.is_jmp = DISAS_STOP;
487 return;
488 case 0xf7fd:
489 CHECK_SH4A
490 tcg_gen_xori_i32(cpu_fpscr, cpu_fpscr, FPSCR_PR);
491 ctx->base.is_jmp = DISAS_STOP;
492 return;
493 case 0x0009:
494 return;
495 case 0x001b:
496 CHECK_PRIVILEGED
497 tcg_gen_movi_i32(cpu_pc, ctx->base.pc_next + 2);
498 gen_helper_sleep(cpu_env);
499 return;
500 }
501
502 switch (ctx->opcode & 0xf000) {
503 case 0x1000:
504 {
505 TCGv addr = tcg_temp_new();
506 tcg_gen_addi_i32(addr, REG(B11_8), B3_0 * 4);
507 tcg_gen_qemu_st_i32(REG(B7_4), addr, ctx->memidx, MO_TEUL);
508 tcg_temp_free(addr);
509 }
510 return;
511 case 0x5000:
512 {
513 TCGv addr = tcg_temp_new();
514 tcg_gen_addi_i32(addr, REG(B7_4), B3_0 * 4);
515 tcg_gen_qemu_ld_i32(REG(B11_8), addr, ctx->memidx, MO_TESL);
516 tcg_temp_free(addr);
517 }
518 return;
519 case 0xe000:
520#ifdef CONFIG_USER_ONLY
521
522
523
524 if (B11_8 == 15 && B7_0s < 0 &&
525 (tb_cflags(ctx->base.tb) & CF_PARALLEL)) {
526 ctx->envflags = deposit32(ctx->envflags, GUSA_SHIFT, 8, B7_0s);
527 ctx->base.is_jmp = DISAS_STOP;
528 }
529#endif
530 tcg_gen_movi_i32(REG(B11_8), B7_0s);
531 return;
532 case 0x9000:
533 {
534 TCGv addr = tcg_const_i32(ctx->base.pc_next + 4 + B7_0 * 2);
535 tcg_gen_qemu_ld_i32(REG(B11_8), addr, ctx->memidx, MO_TESW);
536 tcg_temp_free(addr);
537 }
538 return;
539 case 0xd000:
540 {
541 TCGv addr = tcg_const_i32((ctx->base.pc_next + 4 + B7_0 * 4) & ~3);
542 tcg_gen_qemu_ld_i32(REG(B11_8), addr, ctx->memidx, MO_TESL);
543 tcg_temp_free(addr);
544 }
545 return;
546 case 0x7000:
547 tcg_gen_addi_i32(REG(B11_8), REG(B11_8), B7_0s);
548 return;
549 case 0xa000:
550 CHECK_NOT_DELAY_SLOT
551 ctx->delayed_pc = ctx->base.pc_next + 4 + B11_0s * 2;
552 ctx->envflags |= DELAY_SLOT;
553 return;
554 case 0xb000:
555 CHECK_NOT_DELAY_SLOT
556 tcg_gen_movi_i32(cpu_pr, ctx->base.pc_next + 4);
557 ctx->delayed_pc = ctx->base.pc_next + 4 + B11_0s * 2;
558 ctx->envflags |= DELAY_SLOT;
559 return;
560 }
561
562 switch (ctx->opcode & 0xf00f) {
563 case 0x6003:
564 tcg_gen_mov_i32(REG(B11_8), REG(B7_4));
565 return;
566 case 0x2000:
567 tcg_gen_qemu_st_i32(REG(B7_4), REG(B11_8), ctx->memidx, MO_UB);
568 return;
569 case 0x2001:
570 tcg_gen_qemu_st_i32(REG(B7_4), REG(B11_8), ctx->memidx, MO_TEUW);
571 return;
572 case 0x2002:
573 tcg_gen_qemu_st_i32(REG(B7_4), REG(B11_8), ctx->memidx, MO_TEUL);
574 return;
575 case 0x6000:
576 tcg_gen_qemu_ld_i32(REG(B11_8), REG(B7_4), ctx->memidx, MO_SB);
577 return;
578 case 0x6001:
579 tcg_gen_qemu_ld_i32(REG(B11_8), REG(B7_4), ctx->memidx, MO_TESW);
580 return;
581 case 0x6002:
582 tcg_gen_qemu_ld_i32(REG(B11_8), REG(B7_4), ctx->memidx, MO_TESL);
583 return;
584 case 0x2004:
585 {
586 TCGv addr = tcg_temp_new();
587 tcg_gen_subi_i32(addr, REG(B11_8), 1);
588
589 tcg_gen_qemu_st_i32(REG(B7_4), addr, ctx->memidx, MO_UB);
590 tcg_gen_mov_i32(REG(B11_8), addr);
591 tcg_temp_free(addr);
592 }
593 return;
594 case 0x2005:
595 {
596 TCGv addr = tcg_temp_new();
597 tcg_gen_subi_i32(addr, REG(B11_8), 2);
598 tcg_gen_qemu_st_i32(REG(B7_4), addr, ctx->memidx, MO_TEUW);
599 tcg_gen_mov_i32(REG(B11_8), addr);
600 tcg_temp_free(addr);
601 }
602 return;
603 case 0x2006:
604 {
605 TCGv addr = tcg_temp_new();
606 tcg_gen_subi_i32(addr, REG(B11_8), 4);
607 tcg_gen_qemu_st_i32(REG(B7_4), addr, ctx->memidx, MO_TEUL);
608 tcg_gen_mov_i32(REG(B11_8), addr);
609 tcg_temp_free(addr);
610 }
611 return;
612 case 0x6004:
613 tcg_gen_qemu_ld_i32(REG(B11_8), REG(B7_4), ctx->memidx, MO_SB);
614 if ( B11_8 != B7_4 )
615 tcg_gen_addi_i32(REG(B7_4), REG(B7_4), 1);
616 return;
617 case 0x6005:
618 tcg_gen_qemu_ld_i32(REG(B11_8), REG(B7_4), ctx->memidx, MO_TESW);
619 if ( B11_8 != B7_4 )
620 tcg_gen_addi_i32(REG(B7_4), REG(B7_4), 2);
621 return;
622 case 0x6006:
623 tcg_gen_qemu_ld_i32(REG(B11_8), REG(B7_4), ctx->memidx, MO_TESL);
624 if ( B11_8 != B7_4 )
625 tcg_gen_addi_i32(REG(B7_4), REG(B7_4), 4);
626 return;
627 case 0x0004:
628 {
629 TCGv addr = tcg_temp_new();
630 tcg_gen_add_i32(addr, REG(B11_8), REG(0));
631 tcg_gen_qemu_st_i32(REG(B7_4), addr, ctx->memidx, MO_UB);
632 tcg_temp_free(addr);
633 }
634 return;
635 case 0x0005:
636 {
637 TCGv addr = tcg_temp_new();
638 tcg_gen_add_i32(addr, REG(B11_8), REG(0));
639 tcg_gen_qemu_st_i32(REG(B7_4), addr, ctx->memidx, MO_TEUW);
640 tcg_temp_free(addr);
641 }
642 return;
643 case 0x0006:
644 {
645 TCGv addr = tcg_temp_new();
646 tcg_gen_add_i32(addr, REG(B11_8), REG(0));
647 tcg_gen_qemu_st_i32(REG(B7_4), addr, ctx->memidx, MO_TEUL);
648 tcg_temp_free(addr);
649 }
650 return;
651 case 0x000c:
652 {
653 TCGv addr = tcg_temp_new();
654 tcg_gen_add_i32(addr, REG(B7_4), REG(0));
655 tcg_gen_qemu_ld_i32(REG(B11_8), addr, ctx->memidx, MO_SB);
656 tcg_temp_free(addr);
657 }
658 return;
659 case 0x000d:
660 {
661 TCGv addr = tcg_temp_new();
662 tcg_gen_add_i32(addr, REG(B7_4), REG(0));
663 tcg_gen_qemu_ld_i32(REG(B11_8), addr, ctx->memidx, MO_TESW);
664 tcg_temp_free(addr);
665 }
666 return;
667 case 0x000e:
668 {
669 TCGv addr = tcg_temp_new();
670 tcg_gen_add_i32(addr, REG(B7_4), REG(0));
671 tcg_gen_qemu_ld_i32(REG(B11_8), addr, ctx->memidx, MO_TESL);
672 tcg_temp_free(addr);
673 }
674 return;
675 case 0x6008:
676 {
677 TCGv low = tcg_temp_new();
678 tcg_gen_ext16u_i32(low, REG(B7_4));
679 tcg_gen_bswap16_i32(low, low);
680 tcg_gen_deposit_i32(REG(B11_8), REG(B7_4), low, 0, 16);
681 tcg_temp_free(low);
682 }
683 return;
684 case 0x6009:
685 tcg_gen_rotli_i32(REG(B11_8), REG(B7_4), 16);
686 return;
687 case 0x200d:
688 {
689 TCGv high, low;
690 high = tcg_temp_new();
691 tcg_gen_shli_i32(high, REG(B7_4), 16);
692 low = tcg_temp_new();
693 tcg_gen_shri_i32(low, REG(B11_8), 16);
694 tcg_gen_or_i32(REG(B11_8), high, low);
695 tcg_temp_free(low);
696 tcg_temp_free(high);
697 }
698 return;
699 case 0x300c:
700 tcg_gen_add_i32(REG(B11_8), REG(B11_8), REG(B7_4));
701 return;
702 case 0x300e:
703 {
704 TCGv t0, t1;
705 t0 = tcg_const_tl(0);
706 t1 = tcg_temp_new();
707 tcg_gen_add2_i32(t1, cpu_sr_t, cpu_sr_t, t0, REG(B7_4), t0);
708 tcg_gen_add2_i32(REG(B11_8), cpu_sr_t,
709 REG(B11_8), t0, t1, cpu_sr_t);
710 tcg_temp_free(t0);
711 tcg_temp_free(t1);
712 }
713 return;
714 case 0x300f:
715 {
716 TCGv t0, t1, t2;
717 t0 = tcg_temp_new();
718 tcg_gen_add_i32(t0, REG(B7_4), REG(B11_8));
719 t1 = tcg_temp_new();
720 tcg_gen_xor_i32(t1, t0, REG(B11_8));
721 t2 = tcg_temp_new();
722 tcg_gen_xor_i32(t2, REG(B7_4), REG(B11_8));
723 tcg_gen_andc_i32(cpu_sr_t, t1, t2);
724 tcg_temp_free(t2);
725 tcg_gen_shri_i32(cpu_sr_t, cpu_sr_t, 31);
726 tcg_temp_free(t1);
727 tcg_gen_mov_i32(REG(B7_4), t0);
728 tcg_temp_free(t0);
729 }
730 return;
731 case 0x2009:
732 tcg_gen_and_i32(REG(B11_8), REG(B11_8), REG(B7_4));
733 return;
734 case 0x3000:
735 tcg_gen_setcond_i32(TCG_COND_EQ, cpu_sr_t, REG(B11_8), REG(B7_4));
736 return;
737 case 0x3003:
738 tcg_gen_setcond_i32(TCG_COND_GE, cpu_sr_t, REG(B11_8), REG(B7_4));
739 return;
740 case 0x3007:
741 tcg_gen_setcond_i32(TCG_COND_GT, cpu_sr_t, REG(B11_8), REG(B7_4));
742 return;
743 case 0x3006:
744 tcg_gen_setcond_i32(TCG_COND_GTU, cpu_sr_t, REG(B11_8), REG(B7_4));
745 return;
746 case 0x3002:
747 tcg_gen_setcond_i32(TCG_COND_GEU, cpu_sr_t, REG(B11_8), REG(B7_4));
748 return;
749 case 0x200c:
750 {
751 TCGv cmp1 = tcg_temp_new();
752 TCGv cmp2 = tcg_temp_new();
753 tcg_gen_xor_i32(cmp2, REG(B7_4), REG(B11_8));
754 tcg_gen_subi_i32(cmp1, cmp2, 0x01010101);
755 tcg_gen_andc_i32(cmp1, cmp1, cmp2);
756 tcg_gen_andi_i32(cmp1, cmp1, 0x80808080);
757 tcg_gen_setcondi_i32(TCG_COND_NE, cpu_sr_t, cmp1, 0);
758 tcg_temp_free(cmp2);
759 tcg_temp_free(cmp1);
760 }
761 return;
762 case 0x2007:
763 tcg_gen_shri_i32(cpu_sr_q, REG(B11_8), 31);
764 tcg_gen_shri_i32(cpu_sr_m, REG(B7_4), 31);
765 tcg_gen_xor_i32(cpu_sr_t, cpu_sr_q, cpu_sr_m);
766 return;
767 case 0x3004:
768 {
769 TCGv t0 = tcg_temp_new();
770 TCGv t1 = tcg_temp_new();
771 TCGv t2 = tcg_temp_new();
772 TCGv zero = tcg_const_i32(0);
773
774
775
776 tcg_gen_shri_i32(t0, REG(B11_8), 31);
777 tcg_gen_shli_i32(REG(B11_8), REG(B11_8), 1);
778 tcg_gen_or_i32(REG(B11_8), REG(B11_8), cpu_sr_t);
779
780
781
782
783
784 tcg_gen_xor_i32(t1, cpu_sr_q, cpu_sr_m);
785 tcg_gen_subi_i32(t1, t1, 1);
786 tcg_gen_neg_i32(t2, REG(B7_4));
787 tcg_gen_movcond_i32(TCG_COND_EQ, t2, t1, zero, REG(B7_4), t2);
788 tcg_gen_add2_i32(REG(B11_8), t1, REG(B11_8), zero, t2, t1);
789
790
791 tcg_gen_andi_i32(t1, t1, 1);
792 tcg_gen_xor_i32(t1, t1, t0);
793 tcg_gen_xori_i32(cpu_sr_t, t1, 1);
794 tcg_gen_xor_i32(cpu_sr_q, cpu_sr_m, t1);
795
796 tcg_temp_free(zero);
797 tcg_temp_free(t2);
798 tcg_temp_free(t1);
799 tcg_temp_free(t0);
800 }
801 return;
802 case 0x300d:
803 tcg_gen_muls2_i32(cpu_macl, cpu_mach, REG(B7_4), REG(B11_8));
804 return;
805 case 0x3005:
806 tcg_gen_mulu2_i32(cpu_macl, cpu_mach, REG(B7_4), REG(B11_8));
807 return;
808 case 0x600e:
809 tcg_gen_ext8s_i32(REG(B11_8), REG(B7_4));
810 return;
811 case 0x600f:
812 tcg_gen_ext16s_i32(REG(B11_8), REG(B7_4));
813 return;
814 case 0x600c:
815 tcg_gen_ext8u_i32(REG(B11_8), REG(B7_4));
816 return;
817 case 0x600d:
818 tcg_gen_ext16u_i32(REG(B11_8), REG(B7_4));
819 return;
820 case 0x000f:
821 {
822 TCGv arg0, arg1;
823 arg0 = tcg_temp_new();
824 tcg_gen_qemu_ld_i32(arg0, REG(B7_4), ctx->memidx, MO_TESL);
825 arg1 = tcg_temp_new();
826 tcg_gen_qemu_ld_i32(arg1, REG(B11_8), ctx->memidx, MO_TESL);
827 gen_helper_macl(cpu_env, arg0, arg1);
828 tcg_temp_free(arg1);
829 tcg_temp_free(arg0);
830 tcg_gen_addi_i32(REG(B7_4), REG(B7_4), 4);
831 tcg_gen_addi_i32(REG(B11_8), REG(B11_8), 4);
832 }
833 return;
834 case 0x400f:
835 {
836 TCGv arg0, arg1;
837 arg0 = tcg_temp_new();
838 tcg_gen_qemu_ld_i32(arg0, REG(B7_4), ctx->memidx, MO_TESL);
839 arg1 = tcg_temp_new();
840 tcg_gen_qemu_ld_i32(arg1, REG(B11_8), ctx->memidx, MO_TESL);
841 gen_helper_macw(cpu_env, arg0, arg1);
842 tcg_temp_free(arg1);
843 tcg_temp_free(arg0);
844 tcg_gen_addi_i32(REG(B11_8), REG(B11_8), 2);
845 tcg_gen_addi_i32(REG(B7_4), REG(B7_4), 2);
846 }
847 return;
848 case 0x0007:
849 tcg_gen_mul_i32(cpu_macl, REG(B7_4), REG(B11_8));
850 return;
851 case 0x200f:
852 {
853 TCGv arg0, arg1;
854 arg0 = tcg_temp_new();
855 tcg_gen_ext16s_i32(arg0, REG(B7_4));
856 arg1 = tcg_temp_new();
857 tcg_gen_ext16s_i32(arg1, REG(B11_8));
858 tcg_gen_mul_i32(cpu_macl, arg0, arg1);
859 tcg_temp_free(arg1);
860 tcg_temp_free(arg0);
861 }
862 return;
863 case 0x200e:
864 {
865 TCGv arg0, arg1;
866 arg0 = tcg_temp_new();
867 tcg_gen_ext16u_i32(arg0, REG(B7_4));
868 arg1 = tcg_temp_new();
869 tcg_gen_ext16u_i32(arg1, REG(B11_8));
870 tcg_gen_mul_i32(cpu_macl, arg0, arg1);
871 tcg_temp_free(arg1);
872 tcg_temp_free(arg0);
873 }
874 return;
875 case 0x600b:
876 tcg_gen_neg_i32(REG(B11_8), REG(B7_4));
877 return;
878 case 0x600a:
879 {
880 TCGv t0 = tcg_const_i32(0);
881 tcg_gen_add2_i32(REG(B11_8), cpu_sr_t,
882 REG(B7_4), t0, cpu_sr_t, t0);
883 tcg_gen_sub2_i32(REG(B11_8), cpu_sr_t,
884 t0, t0, REG(B11_8), cpu_sr_t);
885 tcg_gen_andi_i32(cpu_sr_t, cpu_sr_t, 1);
886 tcg_temp_free(t0);
887 }
888 return;
889 case 0x6007:
890 tcg_gen_not_i32(REG(B11_8), REG(B7_4));
891 return;
892 case 0x200b:
893 tcg_gen_or_i32(REG(B11_8), REG(B11_8), REG(B7_4));
894 return;
895 case 0x400c:
896 {
897 TCGv t0 = tcg_temp_new();
898 TCGv t1 = tcg_temp_new();
899 TCGv t2 = tcg_temp_new();
900
901 tcg_gen_andi_i32(t0, REG(B7_4), 0x1f);
902
903
904 tcg_gen_shl_i32(t1, REG(B11_8), t0);
905
906
907
908 tcg_gen_xori_i32(t0, t0, 0x1f);
909 tcg_gen_sar_i32(t2, REG(B11_8), t0);
910 tcg_gen_sari_i32(t2, t2, 1);
911
912
913 tcg_gen_movi_i32(t0, 0);
914 tcg_gen_movcond_i32(TCG_COND_GE, REG(B11_8), REG(B7_4), t0, t1, t2);
915
916 tcg_temp_free(t0);
917 tcg_temp_free(t1);
918 tcg_temp_free(t2);
919 }
920 return;
921 case 0x400d:
922 {
923 TCGv t0 = tcg_temp_new();
924 TCGv t1 = tcg_temp_new();
925 TCGv t2 = tcg_temp_new();
926
927 tcg_gen_andi_i32(t0, REG(B7_4), 0x1f);
928
929
930 tcg_gen_shl_i32(t1, REG(B11_8), t0);
931
932
933
934 tcg_gen_xori_i32(t0, t0, 0x1f);
935 tcg_gen_shr_i32(t2, REG(B11_8), t0);
936 tcg_gen_shri_i32(t2, t2, 1);
937
938
939 tcg_gen_movi_i32(t0, 0);
940 tcg_gen_movcond_i32(TCG_COND_GE, REG(B11_8), REG(B7_4), t0, t1, t2);
941
942 tcg_temp_free(t0);
943 tcg_temp_free(t1);
944 tcg_temp_free(t2);
945 }
946 return;
947 case 0x3008:
948 tcg_gen_sub_i32(REG(B11_8), REG(B11_8), REG(B7_4));
949 return;
950 case 0x300a:
951 {
952 TCGv t0, t1;
953 t0 = tcg_const_tl(0);
954 t1 = tcg_temp_new();
955 tcg_gen_add2_i32(t1, cpu_sr_t, cpu_sr_t, t0, REG(B7_4), t0);
956 tcg_gen_sub2_i32(REG(B11_8), cpu_sr_t,
957 REG(B11_8), t0, t1, cpu_sr_t);
958 tcg_gen_andi_i32(cpu_sr_t, cpu_sr_t, 1);
959 tcg_temp_free(t0);
960 tcg_temp_free(t1);
961 }
962 return;
963 case 0x300b:
964 {
965 TCGv t0, t1, t2;
966 t0 = tcg_temp_new();
967 tcg_gen_sub_i32(t0, REG(B11_8), REG(B7_4));
968 t1 = tcg_temp_new();
969 tcg_gen_xor_i32(t1, t0, REG(B7_4));
970 t2 = tcg_temp_new();
971 tcg_gen_xor_i32(t2, REG(B11_8), REG(B7_4));
972 tcg_gen_and_i32(t1, t1, t2);
973 tcg_temp_free(t2);
974 tcg_gen_shri_i32(cpu_sr_t, t1, 31);
975 tcg_temp_free(t1);
976 tcg_gen_mov_i32(REG(B11_8), t0);
977 tcg_temp_free(t0);
978 }
979 return;
980 case 0x2008:
981 {
982 TCGv val = tcg_temp_new();
983 tcg_gen_and_i32(val, REG(B7_4), REG(B11_8));
984 tcg_gen_setcondi_i32(TCG_COND_EQ, cpu_sr_t, val, 0);
985 tcg_temp_free(val);
986 }
987 return;
988 case 0x200a:
989 tcg_gen_xor_i32(REG(B11_8), REG(B11_8), REG(B7_4));
990 return;
991 case 0xf00c:
992 CHECK_FPU_ENABLED
993 if (ctx->tbflags & FPSCR_SZ) {
994 int xsrc = XHACK(B7_4);
995 int xdst = XHACK(B11_8);
996 tcg_gen_mov_i32(FREG(xdst), FREG(xsrc));
997 tcg_gen_mov_i32(FREG(xdst + 1), FREG(xsrc + 1));
998 } else {
999 tcg_gen_mov_i32(FREG(B11_8), FREG(B7_4));
1000 }
1001 return;
1002 case 0xf00a:
1003 CHECK_FPU_ENABLED
1004 if (ctx->tbflags & FPSCR_SZ) {
1005 TCGv_i64 fp = tcg_temp_new_i64();
1006 gen_load_fpr64(ctx, fp, XHACK(B7_4));
1007 tcg_gen_qemu_st_i64(fp, REG(B11_8), ctx->memidx, MO_TEQ);
1008 tcg_temp_free_i64(fp);
1009 } else {
1010 tcg_gen_qemu_st_i32(FREG(B7_4), REG(B11_8), ctx->memidx, MO_TEUL);
1011 }
1012 return;
1013 case 0xf008:
1014 CHECK_FPU_ENABLED
1015 if (ctx->tbflags & FPSCR_SZ) {
1016 TCGv_i64 fp = tcg_temp_new_i64();
1017 tcg_gen_qemu_ld_i64(fp, REG(B7_4), ctx->memidx, MO_TEQ);
1018 gen_store_fpr64(ctx, fp, XHACK(B11_8));
1019 tcg_temp_free_i64(fp);
1020 } else {
1021 tcg_gen_qemu_ld_i32(FREG(B11_8), REG(B7_4), ctx->memidx, MO_TEUL);
1022 }
1023 return;
1024 case 0xf009:
1025 CHECK_FPU_ENABLED
1026 if (ctx->tbflags & FPSCR_SZ) {
1027 TCGv_i64 fp = tcg_temp_new_i64();
1028 tcg_gen_qemu_ld_i64(fp, REG(B7_4), ctx->memidx, MO_TEQ);
1029 gen_store_fpr64(ctx, fp, XHACK(B11_8));
1030 tcg_temp_free_i64(fp);
1031 tcg_gen_addi_i32(REG(B7_4), REG(B7_4), 8);
1032 } else {
1033 tcg_gen_qemu_ld_i32(FREG(B11_8), REG(B7_4), ctx->memidx, MO_TEUL);
1034 tcg_gen_addi_i32(REG(B7_4), REG(B7_4), 4);
1035 }
1036 return;
1037 case 0xf00b:
1038 CHECK_FPU_ENABLED
1039 {
1040 TCGv addr = tcg_temp_new_i32();
1041 if (ctx->tbflags & FPSCR_SZ) {
1042 TCGv_i64 fp = tcg_temp_new_i64();
1043 gen_load_fpr64(ctx, fp, XHACK(B7_4));
1044 tcg_gen_subi_i32(addr, REG(B11_8), 8);
1045 tcg_gen_qemu_st_i64(fp, addr, ctx->memidx, MO_TEQ);
1046 tcg_temp_free_i64(fp);
1047 } else {
1048 tcg_gen_subi_i32(addr, REG(B11_8), 4);
1049 tcg_gen_qemu_st_i32(FREG(B7_4), addr, ctx->memidx, MO_TEUL);
1050 }
1051 tcg_gen_mov_i32(REG(B11_8), addr);
1052 tcg_temp_free(addr);
1053 }
1054 return;
1055 case 0xf006:
1056 CHECK_FPU_ENABLED
1057 {
1058 TCGv addr = tcg_temp_new_i32();
1059 tcg_gen_add_i32(addr, REG(B7_4), REG(0));
1060 if (ctx->tbflags & FPSCR_SZ) {
1061 TCGv_i64 fp = tcg_temp_new_i64();
1062 tcg_gen_qemu_ld_i64(fp, addr, ctx->memidx, MO_TEQ);
1063 gen_store_fpr64(ctx, fp, XHACK(B11_8));
1064 tcg_temp_free_i64(fp);
1065 } else {
1066 tcg_gen_qemu_ld_i32(FREG(B11_8), addr, ctx->memidx, MO_TEUL);
1067 }
1068 tcg_temp_free(addr);
1069 }
1070 return;
1071 case 0xf007:
1072 CHECK_FPU_ENABLED
1073 {
1074 TCGv addr = tcg_temp_new();
1075 tcg_gen_add_i32(addr, REG(B11_8), REG(0));
1076 if (ctx->tbflags & FPSCR_SZ) {
1077 TCGv_i64 fp = tcg_temp_new_i64();
1078 gen_load_fpr64(ctx, fp, XHACK(B7_4));
1079 tcg_gen_qemu_st_i64(fp, addr, ctx->memidx, MO_TEQ);
1080 tcg_temp_free_i64(fp);
1081 } else {
1082 tcg_gen_qemu_st_i32(FREG(B7_4), addr, ctx->memidx, MO_TEUL);
1083 }
1084 tcg_temp_free(addr);
1085 }
1086 return;
1087 case 0xf000:
1088 case 0xf001:
1089 case 0xf002:
1090 case 0xf003:
1091 case 0xf004:
1092 case 0xf005:
1093 {
1094 CHECK_FPU_ENABLED
1095 if (ctx->tbflags & FPSCR_PR) {
1096 TCGv_i64 fp0, fp1;
1097
1098 if (ctx->opcode & 0x0110) {
1099 goto do_illegal;
1100 }
1101 fp0 = tcg_temp_new_i64();
1102 fp1 = tcg_temp_new_i64();
1103 gen_load_fpr64(ctx, fp0, B11_8);
1104 gen_load_fpr64(ctx, fp1, B7_4);
1105 switch (ctx->opcode & 0xf00f) {
1106 case 0xf000:
1107 gen_helper_fadd_DT(fp0, cpu_env, fp0, fp1);
1108 break;
1109 case 0xf001:
1110 gen_helper_fsub_DT(fp0, cpu_env, fp0, fp1);
1111 break;
1112 case 0xf002:
1113 gen_helper_fmul_DT(fp0, cpu_env, fp0, fp1);
1114 break;
1115 case 0xf003:
1116 gen_helper_fdiv_DT(fp0, cpu_env, fp0, fp1);
1117 break;
1118 case 0xf004:
1119 gen_helper_fcmp_eq_DT(cpu_sr_t, cpu_env, fp0, fp1);
1120 return;
1121 case 0xf005:
1122 gen_helper_fcmp_gt_DT(cpu_sr_t, cpu_env, fp0, fp1);
1123 return;
1124 }
1125 gen_store_fpr64(ctx, fp0, B11_8);
1126 tcg_temp_free_i64(fp0);
1127 tcg_temp_free_i64(fp1);
1128 } else {
1129 switch (ctx->opcode & 0xf00f) {
1130 case 0xf000:
1131 gen_helper_fadd_FT(FREG(B11_8), cpu_env,
1132 FREG(B11_8), FREG(B7_4));
1133 break;
1134 case 0xf001:
1135 gen_helper_fsub_FT(FREG(B11_8), cpu_env,
1136 FREG(B11_8), FREG(B7_4));
1137 break;
1138 case 0xf002:
1139 gen_helper_fmul_FT(FREG(B11_8), cpu_env,
1140 FREG(B11_8), FREG(B7_4));
1141 break;
1142 case 0xf003:
1143 gen_helper_fdiv_FT(FREG(B11_8), cpu_env,
1144 FREG(B11_8), FREG(B7_4));
1145 break;
1146 case 0xf004:
1147 gen_helper_fcmp_eq_FT(cpu_sr_t, cpu_env,
1148 FREG(B11_8), FREG(B7_4));
1149 return;
1150 case 0xf005:
1151 gen_helper_fcmp_gt_FT(cpu_sr_t, cpu_env,
1152 FREG(B11_8), FREG(B7_4));
1153 return;
1154 }
1155 }
1156 }
1157 return;
1158 case 0xf00e:
1159 CHECK_FPU_ENABLED
1160 CHECK_FPSCR_PR_0
1161 gen_helper_fmac_FT(FREG(B11_8), cpu_env,
1162 FREG(0), FREG(B7_4), FREG(B11_8));
1163 return;
1164 }
1165
1166 switch (ctx->opcode & 0xff00) {
1167 case 0xc900:
1168 tcg_gen_andi_i32(REG(0), REG(0), B7_0);
1169 return;
1170 case 0xcd00:
1171 {
1172 TCGv addr, val;
1173 addr = tcg_temp_new();
1174 tcg_gen_add_i32(addr, REG(0), cpu_gbr);
1175 val = tcg_temp_new();
1176 tcg_gen_qemu_ld_i32(val, addr, ctx->memidx, MO_UB);
1177 tcg_gen_andi_i32(val, val, B7_0);
1178 tcg_gen_qemu_st_i32(val, addr, ctx->memidx, MO_UB);
1179 tcg_temp_free(val);
1180 tcg_temp_free(addr);
1181 }
1182 return;
1183 case 0x8b00:
1184 CHECK_NOT_DELAY_SLOT
1185 gen_conditional_jump(ctx, ctx->base.pc_next + 4 + B7_0s * 2, false);
1186 return;
1187 case 0x8f00:
1188 CHECK_NOT_DELAY_SLOT
1189 tcg_gen_xori_i32(cpu_delayed_cond, cpu_sr_t, 1);
1190 ctx->delayed_pc = ctx->base.pc_next + 4 + B7_0s * 2;
1191 ctx->envflags |= DELAY_SLOT_CONDITIONAL;
1192 return;
1193 case 0x8900:
1194 CHECK_NOT_DELAY_SLOT
1195 gen_conditional_jump(ctx, ctx->base.pc_next + 4 + B7_0s * 2, true);
1196 return;
1197 case 0x8d00:
1198 CHECK_NOT_DELAY_SLOT
1199 tcg_gen_mov_i32(cpu_delayed_cond, cpu_sr_t);
1200 ctx->delayed_pc = ctx->base.pc_next + 4 + B7_0s * 2;
1201 ctx->envflags |= DELAY_SLOT_CONDITIONAL;
1202 return;
1203 case 0x8800:
1204 tcg_gen_setcondi_i32(TCG_COND_EQ, cpu_sr_t, REG(0), B7_0s);
1205 return;
1206 case 0xc400:
1207 {
1208 TCGv addr = tcg_temp_new();
1209 tcg_gen_addi_i32(addr, cpu_gbr, B7_0);
1210 tcg_gen_qemu_ld_i32(REG(0), addr, ctx->memidx, MO_SB);
1211 tcg_temp_free(addr);
1212 }
1213 return;
1214 case 0xc500:
1215 {
1216 TCGv addr = tcg_temp_new();
1217 tcg_gen_addi_i32(addr, cpu_gbr, B7_0 * 2);
1218 tcg_gen_qemu_ld_i32(REG(0), addr, ctx->memidx, MO_TESW);
1219 tcg_temp_free(addr);
1220 }
1221 return;
1222 case 0xc600:
1223 {
1224 TCGv addr = tcg_temp_new();
1225 tcg_gen_addi_i32(addr, cpu_gbr, B7_0 * 4);
1226 tcg_gen_qemu_ld_i32(REG(0), addr, ctx->memidx, MO_TESL);
1227 tcg_temp_free(addr);
1228 }
1229 return;
1230 case 0xc000:
1231 {
1232 TCGv addr = tcg_temp_new();
1233 tcg_gen_addi_i32(addr, cpu_gbr, B7_0);
1234 tcg_gen_qemu_st_i32(REG(0), addr, ctx->memidx, MO_UB);
1235 tcg_temp_free(addr);
1236 }
1237 return;
1238 case 0xc100:
1239 {
1240 TCGv addr = tcg_temp_new();
1241 tcg_gen_addi_i32(addr, cpu_gbr, B7_0 * 2);
1242 tcg_gen_qemu_st_i32(REG(0), addr, ctx->memidx, MO_TEUW);
1243 tcg_temp_free(addr);
1244 }
1245 return;
1246 case 0xc200:
1247 {
1248 TCGv addr = tcg_temp_new();
1249 tcg_gen_addi_i32(addr, cpu_gbr, B7_0 * 4);
1250 tcg_gen_qemu_st_i32(REG(0), addr, ctx->memidx, MO_TEUL);
1251 tcg_temp_free(addr);
1252 }
1253 return;
1254 case 0x8000:
1255 {
1256 TCGv addr = tcg_temp_new();
1257 tcg_gen_addi_i32(addr, REG(B7_4), B3_0);
1258 tcg_gen_qemu_st_i32(REG(0), addr, ctx->memidx, MO_UB);
1259 tcg_temp_free(addr);
1260 }
1261 return;
1262 case 0x8100:
1263 {
1264 TCGv addr = tcg_temp_new();
1265 tcg_gen_addi_i32(addr, REG(B7_4), B3_0 * 2);
1266 tcg_gen_qemu_st_i32(REG(0), addr, ctx->memidx, MO_TEUW);
1267 tcg_temp_free(addr);
1268 }
1269 return;
1270 case 0x8400:
1271 {
1272 TCGv addr = tcg_temp_new();
1273 tcg_gen_addi_i32(addr, REG(B7_4), B3_0);
1274 tcg_gen_qemu_ld_i32(REG(0), addr, ctx->memidx, MO_SB);
1275 tcg_temp_free(addr);
1276 }
1277 return;
1278 case 0x8500:
1279 {
1280 TCGv addr = tcg_temp_new();
1281 tcg_gen_addi_i32(addr, REG(B7_4), B3_0 * 2);
1282 tcg_gen_qemu_ld_i32(REG(0), addr, ctx->memidx, MO_TESW);
1283 tcg_temp_free(addr);
1284 }
1285 return;
1286 case 0xc700:
1287 tcg_gen_movi_i32(REG(0), ((ctx->base.pc_next & 0xfffffffc) +
1288 4 + B7_0 * 4) & ~3);
1289 return;
1290 case 0xcb00:
1291 tcg_gen_ori_i32(REG(0), REG(0), B7_0);
1292 return;
1293 case 0xcf00:
1294 {
1295 TCGv addr, val;
1296 addr = tcg_temp_new();
1297 tcg_gen_add_i32(addr, REG(0), cpu_gbr);
1298 val = tcg_temp_new();
1299 tcg_gen_qemu_ld_i32(val, addr, ctx->memidx, MO_UB);
1300 tcg_gen_ori_i32(val, val, B7_0);
1301 tcg_gen_qemu_st_i32(val, addr, ctx->memidx, MO_UB);
1302 tcg_temp_free(val);
1303 tcg_temp_free(addr);
1304 }
1305 return;
1306 case 0xc300:
1307 {
1308 TCGv imm;
1309 CHECK_NOT_DELAY_SLOT
1310 gen_save_cpu_state(ctx, true);
1311 imm = tcg_const_i32(B7_0);
1312 gen_helper_trapa(cpu_env, imm);
1313 tcg_temp_free(imm);
1314 ctx->base.is_jmp = DISAS_NORETURN;
1315 }
1316 return;
1317 case 0xc800:
1318 {
1319 TCGv val = tcg_temp_new();
1320 tcg_gen_andi_i32(val, REG(0), B7_0);
1321 tcg_gen_setcondi_i32(TCG_COND_EQ, cpu_sr_t, val, 0);
1322 tcg_temp_free(val);
1323 }
1324 return;
1325 case 0xcc00:
1326 {
1327 TCGv val = tcg_temp_new();
1328 tcg_gen_add_i32(val, REG(0), cpu_gbr);
1329 tcg_gen_qemu_ld_i32(val, val, ctx->memidx, MO_UB);
1330 tcg_gen_andi_i32(val, val, B7_0);
1331 tcg_gen_setcondi_i32(TCG_COND_EQ, cpu_sr_t, val, 0);
1332 tcg_temp_free(val);
1333 }
1334 return;
1335 case 0xca00:
1336 tcg_gen_xori_i32(REG(0), REG(0), B7_0);
1337 return;
1338 case 0xce00:
1339 {
1340 TCGv addr, val;
1341 addr = tcg_temp_new();
1342 tcg_gen_add_i32(addr, REG(0), cpu_gbr);
1343 val = tcg_temp_new();
1344 tcg_gen_qemu_ld_i32(val, addr, ctx->memidx, MO_UB);
1345 tcg_gen_xori_i32(val, val, B7_0);
1346 tcg_gen_qemu_st_i32(val, addr, ctx->memidx, MO_UB);
1347 tcg_temp_free(val);
1348 tcg_temp_free(addr);
1349 }
1350 return;
1351 }
1352
1353 switch (ctx->opcode & 0xf08f) {
1354 case 0x408e:
1355 CHECK_PRIVILEGED
1356 tcg_gen_mov_i32(ALTREG(B6_4), REG(B11_8));
1357 return;
1358 case 0x4087:
1359 CHECK_PRIVILEGED
1360 tcg_gen_qemu_ld_i32(ALTREG(B6_4), REG(B11_8), ctx->memidx, MO_TESL);
1361 tcg_gen_addi_i32(REG(B11_8), REG(B11_8), 4);
1362 return;
1363 case 0x0082:
1364 CHECK_PRIVILEGED
1365 tcg_gen_mov_i32(REG(B11_8), ALTREG(B6_4));
1366 return;
1367 case 0x4083:
1368 CHECK_PRIVILEGED
1369 {
1370 TCGv addr = tcg_temp_new();
1371 tcg_gen_subi_i32(addr, REG(B11_8), 4);
1372 tcg_gen_qemu_st_i32(ALTREG(B6_4), addr, ctx->memidx, MO_TEUL);
1373 tcg_gen_mov_i32(REG(B11_8), addr);
1374 tcg_temp_free(addr);
1375 }
1376 return;
1377 }
1378
1379 switch (ctx->opcode & 0xf0ff) {
1380 case 0x0023:
1381 CHECK_NOT_DELAY_SLOT
1382 tcg_gen_addi_i32(cpu_delayed_pc, REG(B11_8), ctx->base.pc_next + 4);
1383 ctx->envflags |= DELAY_SLOT;
1384 ctx->delayed_pc = (uint32_t) - 1;
1385 return;
1386 case 0x0003:
1387 CHECK_NOT_DELAY_SLOT
1388 tcg_gen_movi_i32(cpu_pr, ctx->base.pc_next + 4);
1389 tcg_gen_add_i32(cpu_delayed_pc, REG(B11_8), cpu_pr);
1390 ctx->envflags |= DELAY_SLOT;
1391 ctx->delayed_pc = (uint32_t) - 1;
1392 return;
1393 case 0x4015:
1394 tcg_gen_setcondi_i32(TCG_COND_GT, cpu_sr_t, REG(B11_8), 0);
1395 return;
1396 case 0x4011:
1397 tcg_gen_setcondi_i32(TCG_COND_GE, cpu_sr_t, REG(B11_8), 0);
1398 return;
1399 case 0x4010:
1400 tcg_gen_subi_i32(REG(B11_8), REG(B11_8), 1);
1401 tcg_gen_setcondi_i32(TCG_COND_EQ, cpu_sr_t, REG(B11_8), 0);
1402 return;
1403 case 0x402b:
1404 CHECK_NOT_DELAY_SLOT
1405 tcg_gen_mov_i32(cpu_delayed_pc, REG(B11_8));
1406 ctx->envflags |= DELAY_SLOT;
1407 ctx->delayed_pc = (uint32_t) - 1;
1408 return;
1409 case 0x400b:
1410 CHECK_NOT_DELAY_SLOT
1411 tcg_gen_movi_i32(cpu_pr, ctx->base.pc_next + 4);
1412 tcg_gen_mov_i32(cpu_delayed_pc, REG(B11_8));
1413 ctx->envflags |= DELAY_SLOT;
1414 ctx->delayed_pc = (uint32_t) - 1;
1415 return;
1416 case 0x400e:
1417 CHECK_PRIVILEGED
1418 {
1419 TCGv val = tcg_temp_new();
1420 tcg_gen_andi_i32(val, REG(B11_8), 0x700083f3);
1421 gen_write_sr(val);
1422 tcg_temp_free(val);
1423 ctx->base.is_jmp = DISAS_STOP;
1424 }
1425 return;
1426 case 0x4007:
1427 CHECK_PRIVILEGED
1428 {
1429 TCGv val = tcg_temp_new();
1430 tcg_gen_qemu_ld_i32(val, REG(B11_8), ctx->memidx, MO_TESL);
1431 tcg_gen_andi_i32(val, val, 0x700083f3);
1432 gen_write_sr(val);
1433 tcg_temp_free(val);
1434 tcg_gen_addi_i32(REG(B11_8), REG(B11_8), 4);
1435 ctx->base.is_jmp = DISAS_STOP;
1436 }
1437 return;
1438 case 0x0002:
1439 CHECK_PRIVILEGED
1440 gen_read_sr(REG(B11_8));
1441 return;
1442 case 0x4003:
1443 CHECK_PRIVILEGED
1444 {
1445 TCGv addr = tcg_temp_new();
1446 TCGv val = tcg_temp_new();
1447 tcg_gen_subi_i32(addr, REG(B11_8), 4);
1448 gen_read_sr(val);
1449 tcg_gen_qemu_st_i32(val, addr, ctx->memidx, MO_TEUL);
1450 tcg_gen_mov_i32(REG(B11_8), addr);
1451 tcg_temp_free(val);
1452 tcg_temp_free(addr);
1453 }
1454 return;
1455#define LD(reg,ldnum,ldpnum,prechk) \
1456 case ldnum: \
1457 prechk \
1458 tcg_gen_mov_i32 (cpu_##reg, REG(B11_8)); \
1459 return; \
1460 case ldpnum: \
1461 prechk \
1462 tcg_gen_qemu_ld_i32(cpu_##reg, REG(B11_8), ctx->memidx, MO_TESL); \
1463 tcg_gen_addi_i32(REG(B11_8), REG(B11_8), 4); \
1464 return;
1465#define ST(reg,stnum,stpnum,prechk) \
1466 case stnum: \
1467 prechk \
1468 tcg_gen_mov_i32 (REG(B11_8), cpu_##reg); \
1469 return; \
1470 case stpnum: \
1471 prechk \
1472 { \
1473 TCGv addr = tcg_temp_new(); \
1474 tcg_gen_subi_i32(addr, REG(B11_8), 4); \
1475 tcg_gen_qemu_st_i32(cpu_##reg, addr, ctx->memidx, MO_TEUL); \
1476 tcg_gen_mov_i32(REG(B11_8), addr); \
1477 tcg_temp_free(addr); \
1478 } \
1479 return;
1480#define LDST(reg,ldnum,ldpnum,stnum,stpnum,prechk) \
1481 LD(reg,ldnum,ldpnum,prechk) \
1482 ST(reg,stnum,stpnum,prechk)
1483 LDST(gbr, 0x401e, 0x4017, 0x0012, 0x4013, {})
1484 LDST(vbr, 0x402e, 0x4027, 0x0022, 0x4023, CHECK_PRIVILEGED)
1485 LDST(ssr, 0x403e, 0x4037, 0x0032, 0x4033, CHECK_PRIVILEGED)
1486 LDST(spc, 0x404e, 0x4047, 0x0042, 0x4043, CHECK_PRIVILEGED)
1487 ST(sgr, 0x003a, 0x4032, CHECK_PRIVILEGED)
1488 LD(sgr, 0x403a, 0x4036, CHECK_PRIVILEGED CHECK_SH4A)
1489 LDST(dbr, 0x40fa, 0x40f6, 0x00fa, 0x40f2, CHECK_PRIVILEGED)
1490 LDST(mach, 0x400a, 0x4006, 0x000a, 0x4002, {})
1491 LDST(macl, 0x401a, 0x4016, 0x001a, 0x4012, {})
1492 LDST(pr, 0x402a, 0x4026, 0x002a, 0x4022, {})
1493 LDST(fpul, 0x405a, 0x4056, 0x005a, 0x4052, {CHECK_FPU_ENABLED})
1494 case 0x406a:
1495 CHECK_FPU_ENABLED
1496 gen_helper_ld_fpscr(cpu_env, REG(B11_8));
1497 ctx->base.is_jmp = DISAS_STOP;
1498 return;
1499 case 0x4066:
1500 CHECK_FPU_ENABLED
1501 {
1502 TCGv addr = tcg_temp_new();
1503 tcg_gen_qemu_ld_i32(addr, REG(B11_8), ctx->memidx, MO_TESL);
1504 tcg_gen_addi_i32(REG(B11_8), REG(B11_8), 4);
1505 gen_helper_ld_fpscr(cpu_env, addr);
1506 tcg_temp_free(addr);
1507 ctx->base.is_jmp = DISAS_STOP;
1508 }
1509 return;
1510 case 0x006a:
1511 CHECK_FPU_ENABLED
1512 tcg_gen_andi_i32(REG(B11_8), cpu_fpscr, 0x003fffff);
1513 return;
1514 case 0x4062:
1515 CHECK_FPU_ENABLED
1516 {
1517 TCGv addr, val;
1518 val = tcg_temp_new();
1519 tcg_gen_andi_i32(val, cpu_fpscr, 0x003fffff);
1520 addr = tcg_temp_new();
1521 tcg_gen_subi_i32(addr, REG(B11_8), 4);
1522 tcg_gen_qemu_st_i32(val, addr, ctx->memidx, MO_TEUL);
1523 tcg_gen_mov_i32(REG(B11_8), addr);
1524 tcg_temp_free(addr);
1525 tcg_temp_free(val);
1526 }
1527 return;
1528 case 0x00c3:
1529 {
1530 TCGv val = tcg_temp_new();
1531 tcg_gen_qemu_ld_i32(val, REG(B11_8), ctx->memidx, MO_TEUL);
1532 gen_helper_movcal(cpu_env, REG(B11_8), val);
1533 tcg_gen_qemu_st_i32(REG(0), REG(B11_8), ctx->memidx, MO_TEUL);
1534 tcg_temp_free(val);
1535 }
1536 ctx->has_movcal = 1;
1537 return;
1538 case 0x40a9:
1539 CHECK_SH4A
1540
1541 tcg_gen_qemu_ld_i32(REG(0), REG(B11_8), ctx->memidx,
1542 MO_TEUL | MO_UNALN);
1543 return;
1544 break;
1545 case 0x40e9:
1546 CHECK_SH4A
1547
1548 tcg_gen_qemu_ld_i32(REG(0), REG(B11_8), ctx->memidx,
1549 MO_TEUL | MO_UNALN);
1550 tcg_gen_addi_i32(REG(B11_8), REG(B11_8), 4);
1551 return;
1552 break;
1553 case 0x0029:
1554 tcg_gen_mov_i32(REG(B11_8), cpu_sr_t);
1555 return;
1556 case 0x0073:
1557
1558
1559
1560
1561
1562
1563
1564
1565
1566 CHECK_SH4A
1567 {
1568 TCGLabel *fail = gen_new_label();
1569 TCGLabel *done = gen_new_label();
1570
1571 if ((tb_cflags(ctx->base.tb) & CF_PARALLEL)) {
1572 TCGv tmp;
1573
1574 tcg_gen_brcond_i32(TCG_COND_NE, REG(B11_8),
1575 cpu_lock_addr, fail);
1576 tmp = tcg_temp_new();
1577 tcg_gen_atomic_cmpxchg_i32(tmp, REG(B11_8), cpu_lock_value,
1578 REG(0), ctx->memidx, MO_TEUL);
1579 tcg_gen_setcond_i32(TCG_COND_EQ, cpu_sr_t, tmp, cpu_lock_value);
1580 tcg_temp_free(tmp);
1581 } else {
1582 tcg_gen_brcondi_i32(TCG_COND_EQ, cpu_lock_addr, -1, fail);
1583 tcg_gen_qemu_st_i32(REG(0), REG(B11_8), ctx->memidx, MO_TEUL);
1584 tcg_gen_movi_i32(cpu_sr_t, 1);
1585 }
1586 tcg_gen_br(done);
1587
1588 gen_set_label(fail);
1589 tcg_gen_movi_i32(cpu_sr_t, 0);
1590
1591 gen_set_label(done);
1592 tcg_gen_movi_i32(cpu_lock_addr, -1);
1593 }
1594 return;
1595 case 0x0063:
1596
1597
1598
1599
1600
1601
1602
1603
1604 CHECK_SH4A
1605 if ((tb_cflags(ctx->base.tb) & CF_PARALLEL)) {
1606 TCGv tmp = tcg_temp_new();
1607 tcg_gen_mov_i32(tmp, REG(B11_8));
1608 tcg_gen_qemu_ld_i32(REG(0), REG(B11_8), ctx->memidx, MO_TESL);
1609 tcg_gen_mov_i32(cpu_lock_value, REG(0));
1610 tcg_gen_mov_i32(cpu_lock_addr, tmp);
1611 tcg_temp_free(tmp);
1612 } else {
1613 tcg_gen_qemu_ld_i32(REG(0), REG(B11_8), ctx->memidx, MO_TESL);
1614 tcg_gen_movi_i32(cpu_lock_addr, 0);
1615 }
1616 return;
1617 case 0x0093:
1618 {
1619 gen_helper_ocbi(cpu_env, REG(B11_8));
1620 }
1621 return;
1622 case 0x00a3:
1623 case 0x00b3:
1624
1625
1626
1627 return;
1628 case 0x0083:
1629 return;
1630 case 0x00d3:
1631 CHECK_SH4A
1632 return;
1633 case 0x00e3:
1634 CHECK_SH4A
1635 return;
1636 case 0x00ab:
1637 CHECK_SH4A
1638 tcg_gen_mb(TCG_MO_ALL | TCG_BAR_SC);
1639 return;
1640 break;
1641 case 0x4024:
1642 {
1643 TCGv tmp = tcg_temp_new();
1644 tcg_gen_mov_i32(tmp, cpu_sr_t);
1645 tcg_gen_shri_i32(cpu_sr_t, REG(B11_8), 31);
1646 tcg_gen_shli_i32(REG(B11_8), REG(B11_8), 1);
1647 tcg_gen_or_i32(REG(B11_8), REG(B11_8), tmp);
1648 tcg_temp_free(tmp);
1649 }
1650 return;
1651 case 0x4025:
1652 {
1653 TCGv tmp = tcg_temp_new();
1654 tcg_gen_shli_i32(tmp, cpu_sr_t, 31);
1655 tcg_gen_andi_i32(cpu_sr_t, REG(B11_8), 1);
1656 tcg_gen_shri_i32(REG(B11_8), REG(B11_8), 1);
1657 tcg_gen_or_i32(REG(B11_8), REG(B11_8), tmp);
1658 tcg_temp_free(tmp);
1659 }
1660 return;
1661 case 0x4004:
1662 tcg_gen_rotli_i32(REG(B11_8), REG(B11_8), 1);
1663 tcg_gen_andi_i32(cpu_sr_t, REG(B11_8), 0);
1664 return;
1665 case 0x4005:
1666 tcg_gen_andi_i32(cpu_sr_t, REG(B11_8), 0);
1667 tcg_gen_rotri_i32(REG(B11_8), REG(B11_8), 1);
1668 return;
1669 case 0x4000:
1670 case 0x4020:
1671 tcg_gen_shri_i32(cpu_sr_t, REG(B11_8), 31);
1672 tcg_gen_shli_i32(REG(B11_8), REG(B11_8), 1);
1673 return;
1674 case 0x4021:
1675 tcg_gen_andi_i32(cpu_sr_t, REG(B11_8), 1);
1676 tcg_gen_sari_i32(REG(B11_8), REG(B11_8), 1);
1677 return;
1678 case 0x4001:
1679 tcg_gen_andi_i32(cpu_sr_t, REG(B11_8), 1);
1680 tcg_gen_shri_i32(REG(B11_8), REG(B11_8), 1);
1681 return;
1682 case 0x4008:
1683 tcg_gen_shli_i32(REG(B11_8), REG(B11_8), 2);
1684 return;
1685 case 0x4018:
1686 tcg_gen_shli_i32(REG(B11_8), REG(B11_8), 8);
1687 return;
1688 case 0x4028:
1689 tcg_gen_shli_i32(REG(B11_8), REG(B11_8), 16);
1690 return;
1691 case 0x4009:
1692 tcg_gen_shri_i32(REG(B11_8), REG(B11_8), 2);
1693 return;
1694 case 0x4019:
1695 tcg_gen_shri_i32(REG(B11_8), REG(B11_8), 8);
1696 return;
1697 case 0x4029:
1698 tcg_gen_shri_i32(REG(B11_8), REG(B11_8), 16);
1699 return;
1700 case 0x401b:
1701 {
1702 TCGv val = tcg_const_i32(0x80);
1703 tcg_gen_atomic_fetch_or_i32(val, REG(B11_8), val,
1704 ctx->memidx, MO_UB);
1705 tcg_gen_setcondi_i32(TCG_COND_EQ, cpu_sr_t, val, 0);
1706 tcg_temp_free(val);
1707 }
1708 return;
1709 case 0xf00d:
1710 CHECK_FPU_ENABLED
1711 tcg_gen_mov_i32(FREG(B11_8), cpu_fpul);
1712 return;
1713 case 0xf01d:
1714 CHECK_FPU_ENABLED
1715 tcg_gen_mov_i32(cpu_fpul, FREG(B11_8));
1716 return;
1717 case 0xf02d:
1718 CHECK_FPU_ENABLED
1719 if (ctx->tbflags & FPSCR_PR) {
1720 TCGv_i64 fp;
1721 if (ctx->opcode & 0x0100) {
1722 goto do_illegal;
1723 }
1724 fp = tcg_temp_new_i64();
1725 gen_helper_float_DT(fp, cpu_env, cpu_fpul);
1726 gen_store_fpr64(ctx, fp, B11_8);
1727 tcg_temp_free_i64(fp);
1728 }
1729 else {
1730 gen_helper_float_FT(FREG(B11_8), cpu_env, cpu_fpul);
1731 }
1732 return;
1733 case 0xf03d:
1734 CHECK_FPU_ENABLED
1735 if (ctx->tbflags & FPSCR_PR) {
1736 TCGv_i64 fp;
1737 if (ctx->opcode & 0x0100) {
1738 goto do_illegal;
1739 }
1740 fp = tcg_temp_new_i64();
1741 gen_load_fpr64(ctx, fp, B11_8);
1742 gen_helper_ftrc_DT(cpu_fpul, cpu_env, fp);
1743 tcg_temp_free_i64(fp);
1744 }
1745 else {
1746 gen_helper_ftrc_FT(cpu_fpul, cpu_env, FREG(B11_8));
1747 }
1748 return;
1749 case 0xf04d:
1750 CHECK_FPU_ENABLED
1751 tcg_gen_xori_i32(FREG(B11_8), FREG(B11_8), 0x80000000);
1752 return;
1753 case 0xf05d:
1754 CHECK_FPU_ENABLED
1755 tcg_gen_andi_i32(FREG(B11_8), FREG(B11_8), 0x7fffffff);
1756 return;
1757 case 0xf06d:
1758 CHECK_FPU_ENABLED
1759 if (ctx->tbflags & FPSCR_PR) {
1760 if (ctx->opcode & 0x0100) {
1761 goto do_illegal;
1762 }
1763 TCGv_i64 fp = tcg_temp_new_i64();
1764 gen_load_fpr64(ctx, fp, B11_8);
1765 gen_helper_fsqrt_DT(fp, cpu_env, fp);
1766 gen_store_fpr64(ctx, fp, B11_8);
1767 tcg_temp_free_i64(fp);
1768 } else {
1769 gen_helper_fsqrt_FT(FREG(B11_8), cpu_env, FREG(B11_8));
1770 }
1771 return;
1772 case 0xf07d:
1773 CHECK_FPU_ENABLED
1774 CHECK_FPSCR_PR_0
1775 gen_helper_fsrra_FT(FREG(B11_8), cpu_env, FREG(B11_8));
1776 break;
1777 case 0xf08d:
1778 CHECK_FPU_ENABLED
1779 CHECK_FPSCR_PR_0
1780 tcg_gen_movi_i32(FREG(B11_8), 0);
1781 return;
1782 case 0xf09d:
1783 CHECK_FPU_ENABLED
1784 CHECK_FPSCR_PR_0
1785 tcg_gen_movi_i32(FREG(B11_8), 0x3f800000);
1786 return;
1787 case 0xf0ad:
1788 CHECK_FPU_ENABLED
1789 {
1790 TCGv_i64 fp = tcg_temp_new_i64();
1791 gen_helper_fcnvsd_FT_DT(fp, cpu_env, cpu_fpul);
1792 gen_store_fpr64(ctx, fp, B11_8);
1793 tcg_temp_free_i64(fp);
1794 }
1795 return;
1796 case 0xf0bd:
1797 CHECK_FPU_ENABLED
1798 {
1799 TCGv_i64 fp = tcg_temp_new_i64();
1800 gen_load_fpr64(ctx, fp, B11_8);
1801 gen_helper_fcnvds_DT_FT(cpu_fpul, cpu_env, fp);
1802 tcg_temp_free_i64(fp);
1803 }
1804 return;
1805 case 0xf0ed:
1806 CHECK_FPU_ENABLED
1807 CHECK_FPSCR_PR_1
1808 {
1809 TCGv m = tcg_const_i32((ctx->opcode >> 8) & 3);
1810 TCGv n = tcg_const_i32((ctx->opcode >> 10) & 3);
1811 gen_helper_fipr(cpu_env, m, n);
1812 tcg_temp_free(m);
1813 tcg_temp_free(n);
1814 return;
1815 }
1816 break;
1817 case 0xf0fd:
1818 CHECK_FPU_ENABLED
1819 CHECK_FPSCR_PR_1
1820 {
1821 if ((ctx->opcode & 0x0300) != 0x0100) {
1822 goto do_illegal;
1823 }
1824 TCGv n = tcg_const_i32((ctx->opcode >> 10) & 3);
1825 gen_helper_ftrv(cpu_env, n);
1826 tcg_temp_free(n);
1827 return;
1828 }
1829 break;
1830 }
1831#if 0
1832 fprintf(stderr, "unknown instruction 0x%04x at pc 0x%08x\n",
1833 ctx->opcode, ctx->base.pc_next);
1834 fflush(stderr);
1835#endif
1836 do_illegal:
1837 if (ctx->envflags & DELAY_SLOT_MASK) {
1838 do_illegal_slot:
1839 gen_save_cpu_state(ctx, true);
1840 gen_helper_raise_slot_illegal_instruction(cpu_env);
1841 } else {
1842 gen_save_cpu_state(ctx, true);
1843 gen_helper_raise_illegal_instruction(cpu_env);
1844 }
1845 ctx->base.is_jmp = DISAS_NORETURN;
1846 return;
1847
1848 do_fpu_disabled:
1849 gen_save_cpu_state(ctx, true);
1850 if (ctx->envflags & DELAY_SLOT_MASK) {
1851 gen_helper_raise_slot_fpu_disable(cpu_env);
1852 } else {
1853 gen_helper_raise_fpu_disable(cpu_env);
1854 }
1855 ctx->base.is_jmp = DISAS_NORETURN;
1856 return;
1857}
1858
1859static void decode_opc(DisasContext * ctx)
1860{
1861 uint32_t old_flags = ctx->envflags;
1862
1863 _decode_opc(ctx);
1864
1865 if (old_flags & DELAY_SLOT_MASK) {
1866
1867 ctx->envflags &= ~DELAY_SLOT_MASK;
1868
1869
1870
1871 if (ctx->tbflags & GUSA_EXCLUSIVE
1872 && old_flags & DELAY_SLOT_CONDITIONAL) {
1873 gen_delayed_conditional_jump(ctx);
1874 return;
1875 }
1876
1877
1878 ctx->envflags &= ~GUSA_MASK;
1879
1880 tcg_gen_movi_i32(cpu_flags, ctx->envflags);
1881 if (old_flags & DELAY_SLOT_CONDITIONAL) {
1882 gen_delayed_conditional_jump(ctx);
1883 } else {
1884 gen_jump(ctx);
1885 }
1886 }
1887}
1888
1889#ifdef CONFIG_USER_ONLY
1890
1891
1892
1893
1894
1895
1896
1897
1898
1899static void decode_gusa(DisasContext *ctx, CPUSH4State *env)
1900{
1901 uint16_t insns[5];
1902 int ld_adr, ld_dst, ld_mop;
1903 int op_dst, op_src, op_opc;
1904 int mv_src, mt_dst, st_src, st_mop;
1905 TCGv op_arg;
1906 uint32_t pc = ctx->base.pc_next;
1907 uint32_t pc_end = ctx->base.tb->cs_base;
1908 int max_insns = (pc_end - pc) / 2;
1909 int i;
1910
1911
1912
1913 if (max_insns > ARRAY_SIZE(insns)) {
1914 goto fail;
1915 }
1916
1917
1918 for (i = 0; i < max_insns; ++i) {
1919 insns[i] = cpu_lduw_code(env, pc + i * 2);
1920 }
1921
1922 ld_adr = ld_dst = ld_mop = -1;
1923 mv_src = -1;
1924 op_dst = op_src = op_opc = -1;
1925 mt_dst = -1;
1926 st_src = st_mop = -1;
1927 op_arg = NULL;
1928 i = 0;
1929
1930#define NEXT_INSN \
1931 do { if (i >= max_insns) goto fail; ctx->opcode = insns[i++]; } while (0)
1932
1933
1934
1935
1936 NEXT_INSN;
1937 switch (ctx->opcode & 0xf00f) {
1938 case 0x6000:
1939 ld_mop = MO_SB;
1940 break;
1941 case 0x6001:
1942 ld_mop = MO_TESW;
1943 break;
1944 case 0x6002:
1945 ld_mop = MO_TESL;
1946 break;
1947 default:
1948 goto fail;
1949 }
1950 ld_adr = B7_4;
1951 ld_dst = B11_8;
1952 if (ld_adr == ld_dst) {
1953 goto fail;
1954 }
1955
1956 op_dst = ld_dst;
1957
1958
1959
1960
1961 NEXT_INSN;
1962 switch (ctx->opcode & 0xf00f) {
1963 case 0x6003:
1964
1965
1966
1967 op_dst = B11_8;
1968 mv_src = B7_4;
1969 if (op_dst == ld_dst) {
1970
1971 goto fail;
1972 }
1973 if (mv_src != ld_dst) {
1974
1975 op_src = ld_dst;
1976 }
1977 break;
1978
1979 default:
1980
1981 --i;
1982 }
1983
1984
1985
1986
1987 NEXT_INSN;
1988 switch (ctx->opcode & 0xf00f) {
1989 case 0x300c:
1990 op_opc = INDEX_op_add_i32;
1991 goto do_reg_op;
1992 case 0x2009:
1993 op_opc = INDEX_op_and_i32;
1994 goto do_reg_op;
1995 case 0x200a:
1996 op_opc = INDEX_op_xor_i32;
1997 goto do_reg_op;
1998 case 0x200b:
1999 op_opc = INDEX_op_or_i32;
2000 do_reg_op:
2001
2002
2003 if (op_dst != B11_8) {
2004 goto fail;
2005 }
2006 if (op_src < 0) {
2007
2008 op_src = B7_4;
2009 } else if (op_src == B7_4) {
2010
2011
2012
2013
2014 op_src = mv_src;
2015 } else {
2016 goto fail;
2017 }
2018 op_arg = REG(op_src);
2019 break;
2020
2021 case 0x6007:
2022 if (ld_dst != B7_4 || mv_src >= 0) {
2023 goto fail;
2024 }
2025 op_dst = B11_8;
2026 op_opc = INDEX_op_xor_i32;
2027 op_arg = tcg_const_i32(-1);
2028 break;
2029
2030 case 0x7000 ... 0x700f:
2031 if (op_dst != B11_8 || mv_src >= 0) {
2032 goto fail;
2033 }
2034 op_opc = INDEX_op_add_i32;
2035 op_arg = tcg_const_i32(B7_0s);
2036 break;
2037
2038 case 0x3000:
2039
2040
2041
2042 if ((ld_dst == B11_8) + (ld_dst == B7_4) != 1 || mv_src >= 0) {
2043 goto fail;
2044 }
2045 op_opc = INDEX_op_setcond_i32;
2046 op_src = (ld_dst == B11_8 ? B7_4 : B11_8);
2047 op_arg = REG(op_src);
2048
2049 NEXT_INSN;
2050 switch (ctx->opcode & 0xff00) {
2051 case 0x8b00:
2052 case 0x8f00:
2053 if (pc + (i + 1 + B7_0s) * 2 != pc_end) {
2054 goto fail;
2055 }
2056 if ((ctx->opcode & 0xff00) == 0x8b00) {
2057 break;
2058 }
2059
2060
2061
2062 NEXT_INSN;
2063 if ((ctx->opcode & 0xf0ff) == 0x0029) {
2064 mt_dst = B11_8;
2065 } else {
2066 goto fail;
2067 }
2068 break;
2069
2070 default:
2071 goto fail;
2072 }
2073 break;
2074
2075 case 0x2008:
2076
2077 if (ld_dst != B11_8 || ld_dst != B7_4 || mv_src >= 0) {
2078 goto fail;
2079 }
2080 op_opc = INDEX_op_setcond_i32;
2081 op_arg = tcg_const_i32(0);
2082
2083 NEXT_INSN;
2084 if ((ctx->opcode & 0xff00) != 0x8900
2085 || pc + (i + 1 + B7_0s) * 2 != pc_end) {
2086 goto fail;
2087 }
2088 break;
2089
2090 default:
2091
2092 --i;
2093 }
2094
2095
2096
2097
2098
2099 if (i != max_insns - 1) {
2100 goto fail;
2101 }
2102 NEXT_INSN;
2103 switch (ctx->opcode & 0xf00f) {
2104 case 0x2000:
2105 st_mop = MO_UB;
2106 break;
2107 case 0x2001:
2108 st_mop = MO_UW;
2109 break;
2110 case 0x2002:
2111 st_mop = MO_UL;
2112 break;
2113 default:
2114 goto fail;
2115 }
2116
2117 if (ld_adr != B11_8 || st_mop != (ld_mop & MO_SIZE)) {
2118 goto fail;
2119 }
2120 st_src = B7_4;
2121
2122#undef NEXT_INSN
2123
2124
2125
2126
2127 switch (op_opc) {
2128 case -1:
2129
2130 if (st_src == ld_dst || mv_src >= 0) {
2131 goto fail;
2132 }
2133 tcg_gen_atomic_xchg_i32(REG(ld_dst), REG(ld_adr), REG(st_src),
2134 ctx->memidx, ld_mop);
2135 break;
2136
2137 case INDEX_op_add_i32:
2138 if (op_dst != st_src) {
2139 goto fail;
2140 }
2141 if (op_dst == ld_dst && st_mop == MO_UL) {
2142 tcg_gen_atomic_add_fetch_i32(REG(ld_dst), REG(ld_adr),
2143 op_arg, ctx->memidx, ld_mop);
2144 } else {
2145 tcg_gen_atomic_fetch_add_i32(REG(ld_dst), REG(ld_adr),
2146 op_arg, ctx->memidx, ld_mop);
2147 if (op_dst != ld_dst) {
2148
2149
2150 tcg_gen_add_i32(REG(op_dst), REG(ld_dst), op_arg);
2151 }
2152 }
2153 break;
2154
2155 case INDEX_op_and_i32:
2156 if (op_dst != st_src) {
2157 goto fail;
2158 }
2159 if (op_dst == ld_dst) {
2160 tcg_gen_atomic_and_fetch_i32(REG(ld_dst), REG(ld_adr),
2161 op_arg, ctx->memidx, ld_mop);
2162 } else {
2163 tcg_gen_atomic_fetch_and_i32(REG(ld_dst), REG(ld_adr),
2164 op_arg, ctx->memidx, ld_mop);
2165 tcg_gen_and_i32(REG(op_dst), REG(ld_dst), op_arg);
2166 }
2167 break;
2168
2169 case INDEX_op_or_i32:
2170 if (op_dst != st_src) {
2171 goto fail;
2172 }
2173 if (op_dst == ld_dst) {
2174 tcg_gen_atomic_or_fetch_i32(REG(ld_dst), REG(ld_adr),
2175 op_arg, ctx->memidx, ld_mop);
2176 } else {
2177 tcg_gen_atomic_fetch_or_i32(REG(ld_dst), REG(ld_adr),
2178 op_arg, ctx->memidx, ld_mop);
2179 tcg_gen_or_i32(REG(op_dst), REG(ld_dst), op_arg);
2180 }
2181 break;
2182
2183 case INDEX_op_xor_i32:
2184 if (op_dst != st_src) {
2185 goto fail;
2186 }
2187 if (op_dst == ld_dst) {
2188 tcg_gen_atomic_xor_fetch_i32(REG(ld_dst), REG(ld_adr),
2189 op_arg, ctx->memidx, ld_mop);
2190 } else {
2191 tcg_gen_atomic_fetch_xor_i32(REG(ld_dst), REG(ld_adr),
2192 op_arg, ctx->memidx, ld_mop);
2193 tcg_gen_xor_i32(REG(op_dst), REG(ld_dst), op_arg);
2194 }
2195 break;
2196
2197 case INDEX_op_setcond_i32:
2198 if (st_src == ld_dst) {
2199 goto fail;
2200 }
2201 tcg_gen_atomic_cmpxchg_i32(REG(ld_dst), REG(ld_adr), op_arg,
2202 REG(st_src), ctx->memidx, ld_mop);
2203 tcg_gen_setcond_i32(TCG_COND_EQ, cpu_sr_t, REG(ld_dst), op_arg);
2204 if (mt_dst >= 0) {
2205 tcg_gen_mov_i32(REG(mt_dst), cpu_sr_t);
2206 }
2207 break;
2208
2209 default:
2210 g_assert_not_reached();
2211 }
2212
2213
2214 if (op_src < 0 && op_arg) {
2215 tcg_temp_free_i32(op_arg);
2216 }
2217
2218
2219 ctx->envflags &= ~GUSA_MASK;
2220 ctx->base.pc_next = pc_end;
2221 ctx->base.num_insns += max_insns - 1;
2222 return;
2223
2224 fail:
2225 qemu_log_mask(LOG_UNIMP, "Unrecognized gUSA sequence %08x-%08x\n",
2226 pc, pc_end);
2227
2228
2229
2230 ctx->envflags |= GUSA_EXCLUSIVE;
2231 gen_save_cpu_state(ctx, false);
2232 gen_helper_exclusive(cpu_env);
2233 ctx->base.is_jmp = DISAS_NORETURN;
2234
2235
2236
2237
2238
2239 ctx->base.pc_next = pc_end;
2240 ctx->base.num_insns += max_insns - 1;
2241}
2242#endif
2243
2244static void sh4_tr_init_disas_context(DisasContextBase *dcbase, CPUState *cs)
2245{
2246 DisasContext *ctx = container_of(dcbase, DisasContext, base);
2247 CPUSH4State *env = cs->env_ptr;
2248 uint32_t tbflags;
2249 int bound;
2250
2251 ctx->tbflags = tbflags = ctx->base.tb->flags;
2252 ctx->envflags = tbflags & TB_FLAG_ENVFLAGS_MASK;
2253 ctx->memidx = (tbflags & (1u << SR_MD)) == 0 ? 1 : 0;
2254
2255
2256 ctx->delayed_pc = -1;
2257 ctx->features = env->features;
2258 ctx->has_movcal = (tbflags & TB_FLAG_PENDING_MOVCA);
2259 ctx->gbank = ((tbflags & (1 << SR_MD)) &&
2260 (tbflags & (1 << SR_RB))) * 0x10;
2261 ctx->fbank = tbflags & FPSCR_FR ? 0x10 : 0;
2262
2263 if (tbflags & GUSA_MASK) {
2264 uint32_t pc = ctx->base.pc_next;
2265 uint32_t pc_end = ctx->base.tb->cs_base;
2266 int backup = sextract32(ctx->tbflags, GUSA_SHIFT, 8);
2267 int max_insns = (pc_end - pc) / 2;
2268
2269 if (pc != pc_end + backup || max_insns < 2) {
2270
2271
2272 ctx->envflags &= ~GUSA_MASK;
2273 } else if (tbflags & GUSA_EXCLUSIVE) {
2274
2275
2276
2277 ctx->base.max_insns = max_insns;
2278 return;
2279 }
2280 }
2281
2282
2283
2284 bound = -(ctx->base.pc_next | TARGET_PAGE_MASK) / 2;
2285 ctx->base.max_insns = MIN(ctx->base.max_insns, bound);
2286}
2287
2288static void sh4_tr_tb_start(DisasContextBase *dcbase, CPUState *cs)
2289{
2290}
2291
2292static void sh4_tr_insn_start(DisasContextBase *dcbase, CPUState *cs)
2293{
2294 DisasContext *ctx = container_of(dcbase, DisasContext, base);
2295
2296 tcg_gen_insn_start(ctx->base.pc_next, ctx->envflags);
2297}
2298
2299static bool sh4_tr_breakpoint_check(DisasContextBase *dcbase, CPUState *cs,
2300 const CPUBreakpoint *bp)
2301{
2302 DisasContext *ctx = container_of(dcbase, DisasContext, base);
2303
2304
2305 gen_save_cpu_state(ctx, true);
2306 gen_helper_debug(cpu_env);
2307 ctx->base.is_jmp = DISAS_NORETURN;
2308
2309
2310
2311
2312 ctx->base.pc_next += 2;
2313 return true;
2314}
2315
2316static void sh4_tr_translate_insn(DisasContextBase *dcbase, CPUState *cs)
2317{
2318 CPUSH4State *env = cs->env_ptr;
2319 DisasContext *ctx = container_of(dcbase, DisasContext, base);
2320
2321#ifdef CONFIG_USER_ONLY
2322 if (unlikely(ctx->envflags & GUSA_MASK)
2323 && !(ctx->envflags & GUSA_EXCLUSIVE)) {
2324
2325
2326
2327
2328
2329 decode_gusa(ctx, env);
2330 return;
2331 }
2332#endif
2333
2334 ctx->opcode = cpu_lduw_code(env, ctx->base.pc_next);
2335 decode_opc(ctx);
2336 ctx->base.pc_next += 2;
2337}
2338
2339static void sh4_tr_tb_stop(DisasContextBase *dcbase, CPUState *cs)
2340{
2341 DisasContext *ctx = container_of(dcbase, DisasContext, base);
2342
2343 if (ctx->tbflags & GUSA_EXCLUSIVE) {
2344
2345 ctx->envflags &= ~GUSA_MASK;
2346 }
2347
2348 switch (ctx->base.is_jmp) {
2349 case DISAS_STOP:
2350 gen_save_cpu_state(ctx, true);
2351 if (ctx->base.singlestep_enabled) {
2352 gen_helper_debug(cpu_env);
2353 } else {
2354 tcg_gen_exit_tb(NULL, 0);
2355 }
2356 break;
2357 case DISAS_NEXT:
2358 case DISAS_TOO_MANY:
2359 gen_save_cpu_state(ctx, false);
2360 gen_goto_tb(ctx, 0, ctx->base.pc_next);
2361 break;
2362 case DISAS_NORETURN:
2363 break;
2364 default:
2365 g_assert_not_reached();
2366 }
2367}
2368
2369static void sh4_tr_disas_log(const DisasContextBase *dcbase, CPUState *cs)
2370{
2371 qemu_log("IN:\n");
2372 log_target_disas(cs, dcbase->pc_first, dcbase->tb->size);
2373}
2374
2375static const TranslatorOps sh4_tr_ops = {
2376 .init_disas_context = sh4_tr_init_disas_context,
2377 .tb_start = sh4_tr_tb_start,
2378 .insn_start = sh4_tr_insn_start,
2379 .breakpoint_check = sh4_tr_breakpoint_check,
2380 .translate_insn = sh4_tr_translate_insn,
2381 .tb_stop = sh4_tr_tb_stop,
2382 .disas_log = sh4_tr_disas_log,
2383};
2384
2385void gen_intermediate_code(CPUState *cs, TranslationBlock *tb)
2386{
2387 DisasContext ctx;
2388
2389 translator_loop(&sh4_tr_ops, &ctx.base, cs, tb);
2390}
2391
2392void restore_state_to_opc(CPUSH4State *env, TranslationBlock *tb,
2393 target_ulong *data)
2394{
2395 env->pc = data[0];
2396 env->flags = data[1];
2397
2398
2399
2400}
2401