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