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