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