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