1 // SPDX-License-Identifier: LGPL-2.1-or-later
3 * Copyright (C) 2019-2021 Paul Cercueil <paul@crapouillou.net>
6 #include "disassembler.h"
7 #include "interpreter.h"
8 #include "lightrec-private.h"
16 static u32 int_CP0(struct interpreter *inter);
17 static u32 int_CP2(struct interpreter *inter);
18 static u32 int_SPECIAL(struct interpreter *inter);
19 static u32 int_META(struct interpreter *inter);
20 static u32 int_REGIMM(struct interpreter *inter);
21 static u32 int_branch(struct interpreter *inter, u32 pc,
22 union code code, bool branch);
24 typedef u32 (*lightrec_int_func_t)(struct interpreter *inter);
26 static const lightrec_int_func_t int_standard[64];
29 struct lightrec_state *state;
38 static u32 int_get_branch_pc(const struct interpreter *inter)
40 return get_branch_pc(inter->block, inter->offset, 0);
43 static inline u32 int_get_ds_pc(const struct interpreter *inter, s16 imm)
45 return get_ds_pc(inter->block, inter->offset, imm);
48 static inline struct opcode *next_op(const struct interpreter *inter)
53 static inline u32 execute(lightrec_int_func_t func, struct interpreter *inter)
55 return (*func)(inter);
58 static inline u32 lightrec_int_op(struct interpreter *inter)
60 return execute(int_standard[inter->op->i.op], inter);
63 static inline u32 jump_skip(struct interpreter *inter)
65 inter->op = next_op(inter);
68 if (op_flag_sync(inter->op->flags)) {
69 inter->state->current_cycle += inter->cycles;
73 return lightrec_int_op(inter);
76 static inline u32 jump_next(struct interpreter *inter)
78 inter->cycles += lightrec_cycles_of_opcode(inter->state, inter->op->c);
80 if (unlikely(inter->delay_slot))
83 return jump_skip(inter);
86 static inline u32 jump_after_branch(struct interpreter *inter)
88 inter->cycles += lightrec_cycles_of_opcode(inter->state, inter->op->c);
90 if (unlikely(inter->delay_slot))
93 inter->op = next_op(inter);
96 return jump_skip(inter);
99 static void update_cycles_before_branch(struct interpreter *inter)
103 if (!inter->delay_slot) {
104 cycles = lightrec_cycles_of_opcode(inter->state, inter->op->c);
106 if (!op_flag_no_ds(inter->op->flags) &&
107 has_delay_slot(inter->op->c))
108 cycles += lightrec_cycles_of_opcode(inter->state, next_op(inter)->c);
110 inter->cycles += cycles;
111 inter->state->current_cycle += inter->cycles;
112 inter->cycles = -cycles;
116 static bool is_branch_taken(const u32 *reg_cache, union code op)
120 return op.r.op == OP_SPECIAL_JR || op.r.op == OP_SPECIAL_JALR;
125 return reg_cache[op.r.rs] == reg_cache[op.r.rt];
127 return reg_cache[op.r.rs] != reg_cache[op.r.rt];
131 case OP_REGIMM_BLTZAL:
132 return (s32)reg_cache[op.r.rs] < 0;
134 case OP_REGIMM_BGEZAL:
135 return (s32)reg_cache[op.r.rs] >= 0;
144 static u32 int_delay_slot(struct interpreter *inter, u32 pc, bool branch)
146 struct lightrec_state *state = inter->state;
147 u32 *reg_cache = state->regs.gpr;
148 struct opcode new_op, *op = next_op(inter);
150 struct interpreter inter2 = {
152 .cycles = inter->cycles,
156 bool run_first_op = false, dummy_ld = false, save_rs = false,
157 load_in_ds, branch_in_ds = false, branch_at_addr = false,
159 u32 new_rt, old_rs = 0, new_rs = 0;
160 u32 next_pc, ds_next_pc, epc;
162 if (op->i.op == OP_CP0 && op->r.rs == OP_CP0_RFE) {
163 /* When an IRQ happens, the PSX exception handlers (when done)
164 * will jump back to the instruction that was executed right
165 * before the IRQ, unless it was a GTE opcode; in that case, it
166 * jumps to the instruction right after.
167 * Since we will never handle the IRQ right after a GTE opcode,
168 * but on branch boundaries, we need to adjust the return
169 * address so that the GTE opcode is effectively executed.
171 epc = state->regs.cp0[14];
174 op_next = lightrec_read_opcode(state, epc);
175 if (op_next.i.op == OP_CP2)
180 if (inter->delay_slot) {
181 /* The branch opcode was in a delay slot of another branch
182 * opcode. Just return the target address of the second
187 /* An opcode located in the delay slot performing a delayed read
188 * requires special handling; we will always resort to using the
189 * interpreter in that case.
190 * Same goes for when we have a branch in a delay slot of another
192 load_in_ds = opcode_is_load(op->c) || opcode_is_mfc(op->c);
193 branch_in_ds = has_delay_slot(op->c);
196 if (load_in_ds || branch_in_ds)
197 op_next = lightrec_read_opcode(state, pc);
200 /* Verify that the next block actually reads the
201 * destination register of the delay slot opcode. */
202 run_first_op = opcode_reads_register(op_next, op->r.rt);
210 if (load_in_ds && run_first_op) {
213 /* If the first opcode of the next block writes the
214 * regiser used as the address for the load, we need to
215 * reset to the old value after it has been executed,
216 * then restore the new value after the delay slot
217 * opcode has been executed. */
218 save_rs = opcode_reads_register(op->c, op->r.rs) &&
219 opcode_writes_register(op_next, op->r.rs);
221 old_rs = reg_cache[op->r.rs];
223 /* If both the first opcode of the next block and the
224 * delay slot opcode write to the same register, the
225 * value written by the delay slot opcode is
227 dummy_ld = opcode_writes_register(op_next, op->r.rt);
232 } else if (has_delay_slot(op_next)) {
233 /* The first opcode of the next block is a branch, so we
234 * cannot execute it here, because of the load delay.
235 * Just check whether or not the branch would be taken,
236 * and save that info into the interpreter struct. */
237 branch_at_addr = true;
238 branch_taken = is_branch_taken(reg_cache, op_next);
239 pr_debug("Target of impossible branch is a branch, "
240 "%staken.\n", branch_taken ? "" : "not ");
241 inter->cycles += lightrec_cycles_of_opcode(inter->state, op_next);
242 old_rs = reg_cache[op_next.r.rs];
249 /* Execute the first opcode of the next block */
250 lightrec_int_op(&inter2);
253 new_rs = reg_cache[op->r.rs];
254 reg_cache[op->r.rs] = old_rs;
257 inter->cycles += lightrec_cycles_of_opcode(inter->state, op_next);
260 next_pc = int_get_ds_pc(inter, 2);
263 inter2.block = inter->block;
265 inter2.cycles = inter->cycles;
266 inter2.offset = inter->offset + 1;
269 new_rt = reg_cache[op->r.rt];
271 /* Execute delay slot opcode */
272 ds_next_pc = lightrec_int_op(&inter2);
274 if (branch_at_addr) {
275 if (op_next.i.op == OP_SPECIAL)
276 /* TODO: Handle JALR setting $ra */
278 else if (op_next.i.op == OP_J || op_next.i.op == OP_JAL)
279 /* TODO: Handle JAL setting $ra */
280 ds_next_pc = (pc & 0xf0000000) | (op_next.j.imm << 2);
282 ds_next_pc = pc + 4 + ((s16)op_next.i.imm << 2);
285 if (branch_at_addr && !branch_taken) {
286 /* If the branch at the target of the branch opcode is not
287 * taken, we jump to its delay slot */
288 next_pc = pc + sizeof(u32);
289 } else if (branch_at_addr || (!branch && branch_in_ds)) {
290 next_pc = ds_next_pc;
294 reg_cache[op->r.rs] = new_rs;
296 reg_cache[op->r.rt] = new_rt;
298 inter->cycles += lightrec_cycles_of_opcode(inter->state, op->c);
300 if (branch_at_addr && branch_taken) {
301 /* If the branch at the target of the branch opcode is taken,
302 * we execute its delay slot here, and jump to its target
304 op_next = lightrec_read_opcode(state, pc + 4);
311 inter->cycles += lightrec_cycles_of_opcode(inter->state, op_next);
313 pr_debug("Running delay slot of branch at target of impossible "
315 lightrec_int_op(&inter2);
321 static u32 int_unimplemented(struct interpreter *inter)
323 lightrec_set_exit_flags(inter->state, LIGHTREC_EXIT_UNKNOWN_OP);
325 return inter->block->pc + (inter->offset << 2);
328 static u32 int_jump(struct interpreter *inter, bool link)
330 struct lightrec_state *state = inter->state;
331 u32 old_pc = int_get_branch_pc(inter);
332 u32 pc = (old_pc & 0xf0000000) | (inter->op->j.imm << 2);
335 state->regs.gpr[31] = old_pc + 8;
337 if (op_flag_no_ds(inter->op->flags))
340 return int_delay_slot(inter, pc, true);
343 static u32 int_J(struct interpreter *inter)
345 return int_jump(inter, false);
348 static u32 int_JAL(struct interpreter *inter)
350 return int_jump(inter, true);
353 static u32 int_jumpr(struct interpreter *inter, u8 link_reg)
355 struct lightrec_state *state = inter->state;
356 u32 old_pc = int_get_branch_pc(inter);
357 u32 next_pc = state->regs.gpr[inter->op->r.rs];
360 state->regs.gpr[link_reg] = old_pc + 8;
362 if (op_flag_no_ds(inter->op->flags))
365 return int_delay_slot(inter, next_pc, true);
368 static u32 int_special_JR(struct interpreter *inter)
370 return int_jumpr(inter, 0);
373 static u32 int_special_JALR(struct interpreter *inter)
375 return int_jumpr(inter, inter->op->r.rd);
378 static u32 int_do_branch(struct interpreter *inter, u32 old_pc, u32 next_pc)
380 if (!inter->delay_slot && op_flag_local_branch(inter->op->flags) &&
381 (s16)inter->op->c.i.imm >= 0) {
382 next_pc = old_pc + ((1 + (s16)inter->op->c.i.imm) << 2);
383 next_pc = lightrec_emulate_block(inter->state, inter->block, next_pc);
389 static u32 int_branch(struct interpreter *inter, u32 pc,
390 union code code, bool branch)
392 u32 next_pc = pc + 4 + ((s16)code.i.imm << 2);
394 update_cycles_before_branch(inter);
396 if (op_flag_no_ds(inter->op->flags)) {
398 return int_do_branch(inter, pc, next_pc);
400 return jump_next(inter);
403 if (!inter->delay_slot)
404 next_pc = int_delay_slot(inter, next_pc, branch);
407 return int_do_branch(inter, pc, next_pc);
409 if (op_flag_emulate_branch(inter->op->flags))
412 return jump_after_branch(inter);
415 static u32 int_beq(struct interpreter *inter, bool bne)
417 u32 rs, rt, old_pc = int_get_branch_pc(inter);
419 rs = inter->state->regs.gpr[inter->op->i.rs];
420 rt = inter->state->regs.gpr[inter->op->i.rt];
422 return int_branch(inter, old_pc, inter->op->c, (rs == rt) ^ bne);
425 static u32 int_BEQ(struct interpreter *inter)
427 return int_beq(inter, false);
430 static u32 int_BNE(struct interpreter *inter)
432 return int_beq(inter, true);
435 static u32 int_bgez(struct interpreter *inter, bool link, bool lt, bool regimm)
437 u32 old_pc = int_get_branch_pc(inter);
441 inter->state->regs.gpr[31] = old_pc + 8;
443 rs = (s32)inter->state->regs.gpr[inter->op->i.rs];
445 return int_branch(inter, old_pc, inter->op->c,
446 ((regimm && !rs) || rs > 0) ^ lt);
449 static u32 int_regimm_BLTZ(struct interpreter *inter)
451 return int_bgez(inter, false, true, true);
454 static u32 int_regimm_BGEZ(struct interpreter *inter)
456 return int_bgez(inter, false, false, true);
459 static u32 int_regimm_BLTZAL(struct interpreter *inter)
461 return int_bgez(inter, true, true, true);
464 static u32 int_regimm_BGEZAL(struct interpreter *inter)
466 return int_bgez(inter, true, false, true);
469 static u32 int_BLEZ(struct interpreter *inter)
471 return int_bgez(inter, false, true, false);
474 static u32 int_BGTZ(struct interpreter *inter)
476 return int_bgez(inter, false, false, false);
479 static u32 int_cfc(struct interpreter *inter)
481 struct lightrec_state *state = inter->state;
482 const struct opcode *op = inter->op;
485 val = lightrec_mfc(state, op->c);
487 if (likely(op->r.rt))
488 state->regs.gpr[op->r.rt] = val;
490 return jump_next(inter);
493 static u32 int_ctc(struct interpreter *inter)
495 struct lightrec_state *state = inter->state;
496 const struct opcode *op = inter->op;
498 lightrec_mtc(state, op->c, op->r.rd, state->regs.gpr[op->r.rt]);
500 /* If we have a MTC0 or CTC0 to CP0 register 12 (Status) or 13 (Cause),
501 * return early so that the emulator will be able to check software
502 * interrupt status. */
503 if (!op_flag_no_ds(inter->op->flags) &&
504 op->i.op == OP_CP0 && (op->r.rd == 12 || op->r.rd == 13))
505 return int_get_ds_pc(inter, 1);
507 return jump_next(inter);
510 static u32 int_cp0_RFE(struct interpreter *inter)
512 lightrec_rfe(inter->state);
514 return jump_next(inter);
517 static u32 int_CP(struct interpreter *inter)
519 lightrec_cp(inter->state, inter->op->c);
521 return jump_next(inter);
524 static u32 int_ADDI(struct interpreter *inter)
526 u32 *reg_cache = inter->state->regs.gpr;
527 struct opcode_i *op = &inter->op->i;
530 reg_cache[op->rt] = reg_cache[op->rs] + (s32)(s16)op->imm;
532 return jump_next(inter);
535 static u32 int_SLTI(struct interpreter *inter)
537 u32 *reg_cache = inter->state->regs.gpr;
538 struct opcode_i *op = &inter->op->i;
541 reg_cache[op->rt] = (s32)reg_cache[op->rs] < (s32)(s16)op->imm;
543 return jump_next(inter);
546 static u32 int_SLTIU(struct interpreter *inter)
548 u32 *reg_cache = inter->state->regs.gpr;
549 struct opcode_i *op = &inter->op->i;
552 reg_cache[op->rt] = reg_cache[op->rs] < (u32)(s32)(s16)op->imm;
554 return jump_next(inter);
557 static u32 int_ANDI(struct interpreter *inter)
559 u32 *reg_cache = inter->state->regs.gpr;
560 struct opcode_i *op = &inter->op->i;
563 reg_cache[op->rt] = reg_cache[op->rs] & op->imm;
565 return jump_next(inter);
568 static u32 int_ORI(struct interpreter *inter)
570 u32 *reg_cache = inter->state->regs.gpr;
571 struct opcode_i *op = &inter->op->i;
574 reg_cache[op->rt] = reg_cache[op->rs] | op->imm;
576 return jump_next(inter);
579 static u32 int_XORI(struct interpreter *inter)
581 u32 *reg_cache = inter->state->regs.gpr;
582 struct opcode_i *op = &inter->op->i;
585 reg_cache[op->rt] = reg_cache[op->rs] ^ op->imm;
587 return jump_next(inter);
590 static u32 int_LUI(struct interpreter *inter)
592 struct opcode_i *op = &inter->op->i;
594 inter->state->regs.gpr[op->rt] = op->imm << 16;
596 return jump_next(inter);
599 static u32 int_io(struct interpreter *inter, bool is_load)
601 struct opcode_i *op = &inter->op->i;
602 u32 *reg_cache = inter->state->regs.gpr;
603 u32 val, *flags = NULL;
605 if (!inter->load_delay && inter->block)
606 flags = &inter->op->flags;
608 val = lightrec_rw(inter->state, inter->op->c,
609 reg_cache[op->rs], reg_cache[op->rt],
610 flags, inter->block, inter->offset);
612 if (is_load && op->rt)
613 reg_cache[op->rt] = val;
615 return jump_next(inter);
618 static u32 int_load(struct interpreter *inter)
620 return int_io(inter, true);
623 static u32 int_store(struct interpreter *inter)
627 if (likely(!op_flag_smc(inter->op->flags)))
628 return int_io(inter, false);
630 lightrec_rw(inter->state, inter->op->c,
631 inter->state->regs.gpr[inter->op->i.rs],
632 inter->state->regs.gpr[inter->op->i.rt],
633 &inter->op->flags, inter->block, inter->offset);
635 next_pc = int_get_ds_pc(inter, 1);
637 /* Invalidate next PC, to force the rest of the block to be rebuilt */
638 lightrec_invalidate(inter->state, next_pc, 4);
643 static u32 int_LWC2(struct interpreter *inter)
645 return int_io(inter, false);
648 static u32 int_special_SLL(struct interpreter *inter)
650 struct opcode *op = inter->op;
653 if (op->opcode) { /* Handle NOPs */
654 rt = inter->state->regs.gpr[op->r.rt];
655 inter->state->regs.gpr[op->r.rd] = rt << op->r.imm;
658 return jump_next(inter);
661 static u32 int_special_SRL(struct interpreter *inter)
663 struct opcode *op = inter->op;
664 u32 rt = inter->state->regs.gpr[op->r.rt];
666 inter->state->regs.gpr[op->r.rd] = rt >> op->r.imm;
668 return jump_next(inter);
671 static u32 int_special_SRA(struct interpreter *inter)
673 struct opcode *op = inter->op;
674 s32 rt = inter->state->regs.gpr[op->r.rt];
676 inter->state->regs.gpr[op->r.rd] = rt >> op->r.imm;
678 return jump_next(inter);
681 static u32 int_special_SLLV(struct interpreter *inter)
683 struct opcode *op = inter->op;
684 u32 rs = inter->state->regs.gpr[op->r.rs];
685 u32 rt = inter->state->regs.gpr[op->r.rt];
687 inter->state->regs.gpr[op->r.rd] = rt << (rs & 0x1f);
689 return jump_next(inter);
692 static u32 int_special_SRLV(struct interpreter *inter)
694 struct opcode *op = inter->op;
695 u32 rs = inter->state->regs.gpr[op->r.rs];
696 u32 rt = inter->state->regs.gpr[op->r.rt];
698 inter->state->regs.gpr[op->r.rd] = rt >> (rs & 0x1f);
700 return jump_next(inter);
703 static u32 int_special_SRAV(struct interpreter *inter)
705 struct opcode *op = inter->op;
706 u32 rs = inter->state->regs.gpr[op->r.rs];
707 s32 rt = inter->state->regs.gpr[op->r.rt];
709 inter->state->regs.gpr[op->r.rd] = rt >> (rs & 0x1f);
711 return jump_next(inter);
714 static u32 int_syscall_break(struct interpreter *inter)
717 if (inter->op->r.op == OP_SPECIAL_BREAK)
718 lightrec_set_exit_flags(inter->state, LIGHTREC_EXIT_BREAK);
720 lightrec_set_exit_flags(inter->state, LIGHTREC_EXIT_SYSCALL);
722 return int_get_ds_pc(inter, 0);
725 static u32 int_special_MFHI(struct interpreter *inter)
727 u32 *reg_cache = inter->state->regs.gpr;
728 struct opcode_r *op = &inter->op->r;
731 reg_cache[op->rd] = reg_cache[REG_HI];
733 return jump_next(inter);
736 static u32 int_special_MTHI(struct interpreter *inter)
738 u32 *reg_cache = inter->state->regs.gpr;
740 reg_cache[REG_HI] = reg_cache[inter->op->r.rs];
742 return jump_next(inter);
745 static u32 int_special_MFLO(struct interpreter *inter)
747 u32 *reg_cache = inter->state->regs.gpr;
748 struct opcode_r *op = &inter->op->r;
751 reg_cache[op->rd] = reg_cache[REG_LO];
753 return jump_next(inter);
756 static u32 int_special_MTLO(struct interpreter *inter)
758 u32 *reg_cache = inter->state->regs.gpr;
760 reg_cache[REG_LO] = reg_cache[inter->op->r.rs];
762 return jump_next(inter);
765 static u32 int_special_MULT(struct interpreter *inter)
767 u32 *reg_cache = inter->state->regs.gpr;
768 s32 rs = reg_cache[inter->op->r.rs];
769 s32 rt = reg_cache[inter->op->r.rt];
770 u8 reg_lo = get_mult_div_lo(inter->op->c);
771 u8 reg_hi = get_mult_div_hi(inter->op->c);
772 u64 res = (s64)rs * (s64)rt;
774 if (!op_flag_no_hi(inter->op->flags))
775 reg_cache[reg_hi] = res >> 32;
776 if (!op_flag_no_lo(inter->op->flags))
777 reg_cache[reg_lo] = res;
779 return jump_next(inter);
782 static u32 int_special_MULTU(struct interpreter *inter)
784 u32 *reg_cache = inter->state->regs.gpr;
785 u32 rs = reg_cache[inter->op->r.rs];
786 u32 rt = reg_cache[inter->op->r.rt];
787 u8 reg_lo = get_mult_div_lo(inter->op->c);
788 u8 reg_hi = get_mult_div_hi(inter->op->c);
789 u64 res = (u64)rs * (u64)rt;
791 if (!op_flag_no_hi(inter->op->flags))
792 reg_cache[reg_hi] = res >> 32;
793 if (!op_flag_no_lo(inter->op->flags))
794 reg_cache[reg_lo] = res;
796 return jump_next(inter);
799 static u32 int_special_DIV(struct interpreter *inter)
801 u32 *reg_cache = inter->state->regs.gpr;
802 s32 rs = reg_cache[inter->op->r.rs];
803 s32 rt = reg_cache[inter->op->r.rt];
804 u8 reg_lo = get_mult_div_lo(inter->op->c);
805 u8 reg_hi = get_mult_div_hi(inter->op->c);
810 lo = (rs < 0) * 2 - 1;
816 if (!op_flag_no_hi(inter->op->flags))
817 reg_cache[reg_hi] = hi;
818 if (!op_flag_no_lo(inter->op->flags))
819 reg_cache[reg_lo] = lo;
821 return jump_next(inter);
824 static u32 int_special_DIVU(struct interpreter *inter)
826 u32 *reg_cache = inter->state->regs.gpr;
827 u32 rs = reg_cache[inter->op->r.rs];
828 u32 rt = reg_cache[inter->op->r.rt];
829 u8 reg_lo = get_mult_div_lo(inter->op->c);
830 u8 reg_hi = get_mult_div_hi(inter->op->c);
841 if (!op_flag_no_hi(inter->op->flags))
842 reg_cache[reg_hi] = hi;
843 if (!op_flag_no_lo(inter->op->flags))
844 reg_cache[reg_lo] = lo;
846 return jump_next(inter);
849 static u32 int_special_ADD(struct interpreter *inter)
851 u32 *reg_cache = inter->state->regs.gpr;
852 struct opcode_r *op = &inter->op->r;
853 s32 rs = reg_cache[op->rs];
854 s32 rt = reg_cache[op->rt];
857 reg_cache[op->rd] = rs + rt;
859 return jump_next(inter);
862 static u32 int_special_SUB(struct interpreter *inter)
864 u32 *reg_cache = inter->state->regs.gpr;
865 struct opcode_r *op = &inter->op->r;
866 u32 rs = reg_cache[op->rs];
867 u32 rt = reg_cache[op->rt];
870 reg_cache[op->rd] = rs - rt;
872 return jump_next(inter);
875 static u32 int_special_AND(struct interpreter *inter)
877 u32 *reg_cache = inter->state->regs.gpr;
878 struct opcode_r *op = &inter->op->r;
879 u32 rs = reg_cache[op->rs];
880 u32 rt = reg_cache[op->rt];
883 reg_cache[op->rd] = rs & rt;
885 return jump_next(inter);
888 static u32 int_special_OR(struct interpreter *inter)
890 u32 *reg_cache = inter->state->regs.gpr;
891 struct opcode_r *op = &inter->op->r;
892 u32 rs = reg_cache[op->rs];
893 u32 rt = reg_cache[op->rt];
896 reg_cache[op->rd] = rs | rt;
898 return jump_next(inter);
901 static u32 int_special_XOR(struct interpreter *inter)
903 u32 *reg_cache = inter->state->regs.gpr;
904 struct opcode_r *op = &inter->op->r;
905 u32 rs = reg_cache[op->rs];
906 u32 rt = reg_cache[op->rt];
909 reg_cache[op->rd] = rs ^ rt;
911 return jump_next(inter);
914 static u32 int_special_NOR(struct interpreter *inter)
916 u32 *reg_cache = inter->state->regs.gpr;
917 struct opcode_r *op = &inter->op->r;
918 u32 rs = reg_cache[op->rs];
919 u32 rt = reg_cache[op->rt];
922 reg_cache[op->rd] = ~(rs | rt);
924 return jump_next(inter);
927 static u32 int_special_SLT(struct interpreter *inter)
929 u32 *reg_cache = inter->state->regs.gpr;
930 struct opcode_r *op = &inter->op->r;
931 s32 rs = reg_cache[op->rs];
932 s32 rt = reg_cache[op->rt];
935 reg_cache[op->rd] = rs < rt;
937 return jump_next(inter);
940 static u32 int_special_SLTU(struct interpreter *inter)
942 u32 *reg_cache = inter->state->regs.gpr;
943 struct opcode_r *op = &inter->op->r;
944 u32 rs = reg_cache[op->rs];
945 u32 rt = reg_cache[op->rt];
948 reg_cache[op->rd] = rs < rt;
950 return jump_next(inter);
953 static u32 int_META_MOV(struct interpreter *inter)
955 u32 *reg_cache = inter->state->regs.gpr;
956 struct opcode_m *op = &inter->op->m;
959 reg_cache[op->rd] = reg_cache[op->rs];
961 return jump_next(inter);
964 static u32 int_META_EXTC(struct interpreter *inter)
966 u32 *reg_cache = inter->state->regs.gpr;
967 struct opcode_m *op = &inter->op->m;
970 reg_cache[op->rd] = (u32)(s32)(s8)reg_cache[op->rs];
972 return jump_next(inter);
975 static u32 int_META_EXTS(struct interpreter *inter)
977 u32 *reg_cache = inter->state->regs.gpr;
978 struct opcode_m *op = &inter->op->m;
981 reg_cache[op->rd] = (u32)(s32)(s16)reg_cache[op->rs];
983 return jump_next(inter);
986 static u32 int_META_MULT2(struct interpreter *inter)
988 u32 *reg_cache = inter->state->regs.gpr;
989 union code c = inter->op->c;
990 u32 rs = reg_cache[c.r.rs];
991 u8 reg_lo = get_mult_div_lo(c);
992 u8 reg_hi = get_mult_div_hi(c);
994 if (!op_flag_no_lo(inter->op->flags)) {
996 reg_cache[reg_lo] = rs << c.r.op;
998 reg_cache[reg_lo] = 0;
1001 if (!op_flag_no_hi(inter->op->flags)) {
1003 reg_cache[reg_hi] = rs << (c.r.op - 32);
1005 else if (c.i.op == OP_META_MULT2) {
1007 reg_cache[reg_hi] = (s32) rs >> (32 - c.r.op);
1009 reg_cache[reg_hi] = (s32) rs >> 31;
1012 reg_cache[reg_hi] = rs >> (32 - c.r.op);
1014 reg_cache[reg_hi] = 0;
1018 return jump_next(inter);
1021 static u32 int_META_COM(struct interpreter *inter)
1023 u32 *reg_cache = inter->state->regs.gpr;
1024 union code c = inter->op->c;
1027 reg_cache[c.m.rd] = ~reg_cache[c.m.rs];
1029 return jump_next(inter);
1032 static const lightrec_int_func_t int_standard[64] = {
1033 SET_DEFAULT_ELM(int_standard, int_unimplemented),
1034 [OP_SPECIAL] = int_SPECIAL,
1035 [OP_REGIMM] = int_REGIMM,
1040 [OP_BLEZ] = int_BLEZ,
1041 [OP_BGTZ] = int_BGTZ,
1042 [OP_ADDI] = int_ADDI,
1043 [OP_ADDIU] = int_ADDI,
1044 [OP_SLTI] = int_SLTI,
1045 [OP_SLTIU] = int_SLTIU,
1046 [OP_ANDI] = int_ANDI,
1048 [OP_XORI] = int_XORI,
1054 [OP_LWL] = int_load,
1056 [OP_LBU] = int_load,
1057 [OP_LHU] = int_load,
1058 [OP_LWR] = int_load,
1059 [OP_SB] = int_store,
1060 [OP_SH] = int_store,
1061 [OP_SWL] = int_store,
1062 [OP_SW] = int_store,
1063 [OP_SWR] = int_store,
1064 [OP_LWC2] = int_LWC2,
1065 [OP_SWC2] = int_store,
1067 [OP_META] = int_META,
1068 [OP_META_MULT2] = int_META_MULT2,
1069 [OP_META_MULTU2] = int_META_MULT2,
1070 [OP_META_LWU] = int_load,
1071 [OP_META_SWU] = int_store,
1074 static const lightrec_int_func_t int_special[64] = {
1075 SET_DEFAULT_ELM(int_special, int_unimplemented),
1076 [OP_SPECIAL_SLL] = int_special_SLL,
1077 [OP_SPECIAL_SRL] = int_special_SRL,
1078 [OP_SPECIAL_SRA] = int_special_SRA,
1079 [OP_SPECIAL_SLLV] = int_special_SLLV,
1080 [OP_SPECIAL_SRLV] = int_special_SRLV,
1081 [OP_SPECIAL_SRAV] = int_special_SRAV,
1082 [OP_SPECIAL_JR] = int_special_JR,
1083 [OP_SPECIAL_JALR] = int_special_JALR,
1084 [OP_SPECIAL_SYSCALL] = int_syscall_break,
1085 [OP_SPECIAL_BREAK] = int_syscall_break,
1086 [OP_SPECIAL_MFHI] = int_special_MFHI,
1087 [OP_SPECIAL_MTHI] = int_special_MTHI,
1088 [OP_SPECIAL_MFLO] = int_special_MFLO,
1089 [OP_SPECIAL_MTLO] = int_special_MTLO,
1090 [OP_SPECIAL_MULT] = int_special_MULT,
1091 [OP_SPECIAL_MULTU] = int_special_MULTU,
1092 [OP_SPECIAL_DIV] = int_special_DIV,
1093 [OP_SPECIAL_DIVU] = int_special_DIVU,
1094 [OP_SPECIAL_ADD] = int_special_ADD,
1095 [OP_SPECIAL_ADDU] = int_special_ADD,
1096 [OP_SPECIAL_SUB] = int_special_SUB,
1097 [OP_SPECIAL_SUBU] = int_special_SUB,
1098 [OP_SPECIAL_AND] = int_special_AND,
1099 [OP_SPECIAL_OR] = int_special_OR,
1100 [OP_SPECIAL_XOR] = int_special_XOR,
1101 [OP_SPECIAL_NOR] = int_special_NOR,
1102 [OP_SPECIAL_SLT] = int_special_SLT,
1103 [OP_SPECIAL_SLTU] = int_special_SLTU,
1106 static const lightrec_int_func_t int_regimm[64] = {
1107 SET_DEFAULT_ELM(int_regimm, int_unimplemented),
1108 [OP_REGIMM_BLTZ] = int_regimm_BLTZ,
1109 [OP_REGIMM_BGEZ] = int_regimm_BGEZ,
1110 [OP_REGIMM_BLTZAL] = int_regimm_BLTZAL,
1111 [OP_REGIMM_BGEZAL] = int_regimm_BGEZAL,
1114 static const lightrec_int_func_t int_cp0[64] = {
1115 SET_DEFAULT_ELM(int_cp0, int_CP),
1116 [OP_CP0_MFC0] = int_cfc,
1117 [OP_CP0_CFC0] = int_cfc,
1118 [OP_CP0_MTC0] = int_ctc,
1119 [OP_CP0_CTC0] = int_ctc,
1120 [OP_CP0_RFE] = int_cp0_RFE,
1123 static const lightrec_int_func_t int_cp2_basic[64] = {
1124 SET_DEFAULT_ELM(int_cp2_basic, int_CP),
1125 [OP_CP2_BASIC_MFC2] = int_cfc,
1126 [OP_CP2_BASIC_CFC2] = int_cfc,
1127 [OP_CP2_BASIC_MTC2] = int_ctc,
1128 [OP_CP2_BASIC_CTC2] = int_ctc,
1131 static const lightrec_int_func_t int_meta[64] = {
1132 SET_DEFAULT_ELM(int_meta, int_unimplemented),
1133 [OP_META_MOV] = int_META_MOV,
1134 [OP_META_EXTC] = int_META_EXTC,
1135 [OP_META_EXTS] = int_META_EXTS,
1136 [OP_META_COM] = int_META_COM,
1139 static u32 int_SPECIAL(struct interpreter *inter)
1141 lightrec_int_func_t f = int_special[inter->op->r.op];
1143 if (!HAS_DEFAULT_ELM && unlikely(!f))
1144 return int_unimplemented(inter);
1146 return execute(f, inter);
1149 static u32 int_REGIMM(struct interpreter *inter)
1151 lightrec_int_func_t f = int_regimm[inter->op->r.rt];
1153 if (!HAS_DEFAULT_ELM && unlikely(!f))
1154 return int_unimplemented(inter);
1156 return execute(f, inter);
1159 static u32 int_CP0(struct interpreter *inter)
1161 lightrec_int_func_t f = int_cp0[inter->op->r.rs];
1163 if (!HAS_DEFAULT_ELM && unlikely(!f))
1164 return int_CP(inter);
1166 return execute(f, inter);
1169 static u32 int_CP2(struct interpreter *inter)
1171 if (inter->op->r.op == OP_CP2_BASIC) {
1172 lightrec_int_func_t f = int_cp2_basic[inter->op->r.rs];
1173 if (HAS_DEFAULT_ELM || likely(f))
1174 return execute(f, inter);
1177 return int_CP(inter);
1180 static u32 int_META(struct interpreter *inter)
1182 lightrec_int_func_t f = int_meta[inter->op->m.op];
1184 if (!HAS_DEFAULT_ELM && unlikely(!f))
1185 return int_unimplemented(inter);
1187 return execute(f, inter);
1190 static u32 lightrec_emulate_block_list(struct lightrec_state *state,
1191 struct block *block, u32 offset)
1193 struct interpreter inter = {
1197 .op = &block->opcode_list[offset],
1201 pc = lightrec_int_op(&inter);
1203 /* Add the cycles of the last branch */
1204 inter.cycles += lightrec_cycles_of_opcode(inter.state, inter.op->c);
1206 state->current_cycle += inter.cycles;
1211 u32 lightrec_emulate_block(struct lightrec_state *state, struct block *block, u32 pc)
1213 u32 offset = (kunseg(pc) - kunseg(block->pc)) >> 2;
1215 if (offset < block->nb_ops)
1216 return lightrec_emulate_block_list(state, block, offset);
1218 pr_err(PC_FMT" is outside block at "PC_FMT"\n", pc, block->pc);
1220 lightrec_set_exit_flags(state, LIGHTREC_EXIT_SEGFAULT);
1225 static u32 branch_get_next_pc(struct lightrec_state *state, union code c, u32 pc)
1230 return state->regs.gpr[c.r.rs];
1233 return (pc & 0xf0000000) | (c.j.imm << 2);
1235 /* Branch opcodes */
1236 return pc + 4 + ((s16)c.i.imm << 2);
1240 u32 lightrec_handle_load_delay(struct lightrec_state *state,
1241 struct block *block, u32 pc, u32 reg)
1243 union code c = lightrec_read_opcode(state, pc);
1244 struct opcode op[2] = {
1253 struct interpreter inter = {
1260 u32 reg_mask, next_pc;
1262 if (has_delay_slot(c)) {
1263 op[1].c = lightrec_read_opcode(state, pc + 4);
1265 branch_taken = is_branch_taken(state->regs.gpr, c);
1266 next_pc = branch_get_next_pc(state, c, pc);
1268 /* Branch was evaluated, we can write the load opcode's target
1270 state->regs.gpr[reg] = state->temp_reg;
1272 /* Handle JALR / regimm opcodes setting $ra (or any other
1273 * register in the case of JALR) */
1274 reg_mask = (u32)opcode_write_mask(c);
1276 state->regs.gpr[ctz32(reg_mask)] = pc + 8;
1278 /* Handle delay slot of the branch opcode */
1279 pc = int_delay_slot(&inter, next_pc, branch_taken);
1281 /* Make sure we only run one instruction */
1282 inter.delay_slot = true;
1284 lightrec_int_op(&inter);
1287 if (!opcode_writes_register(c, reg))
1288 state->regs.gpr[reg] = state->temp_reg;
1291 state->current_cycle += inter.cycles;