More progress on JIT constant instructions implementations
This commit is contained in:
@@ -23,7 +23,7 @@ void JIT::CheckCompareInterrupt() {
|
||||
}
|
||||
|
||||
int JIT::Step() {
|
||||
u32 instruction;
|
||||
u32 instruction = 0;
|
||||
s64 pc = regs.pc;
|
||||
|
||||
do {
|
||||
@@ -32,19 +32,23 @@ int JIT::Step() {
|
||||
// regs.prevDelaySlot = regs.delaySlot;
|
||||
// regs.delaySlot = false;
|
||||
|
||||
/*if (check_address_error(0b11, u64(pc))) [[unlikely]] {
|
||||
regs.cop0.HandleTLBException(pc);
|
||||
if (check_address_error(0b11, u64(pc))) [[unlikely]] {
|
||||
/*regs.cop0.HandleTLBException(pc);
|
||||
regs.cop0.FireException(ExceptionCode::AddressErrorLoad, 0, pc);
|
||||
return 1;
|
||||
}*/
|
||||
return 1;*/
|
||||
|
||||
Util::panic("[JIT]: Unhandled exception ADL due to unaligned PC virtual value! (0x{:016lX})",
|
||||
static_cast<u64>(regs.pc));
|
||||
}
|
||||
|
||||
u32 paddr = 0;
|
||||
if (!regs.cop0.MapVAddr(Cop0::LOAD, pc, paddr)) {
|
||||
/*regs.cop0.HandleTLBException(pc);
|
||||
regs.cop0.FireException(Cop0::GetTLBExceptionCode(regs.cop0.tlbError, Cop0::LOAD), 0, pc);
|
||||
return 1;*/
|
||||
Util::panic("[JIT]: Unhandled exception TLB exception {} when retrieving PC physical address!",
|
||||
static_cast<int>(Cop0::GetTLBExceptionCode(regs.cop0.tlbError, Cop0::LOAD)));
|
||||
Util::panic(
|
||||
"[JIT]: Unhandled exception TLB exception {} when retrieving PC physical address! (virtual: 0x{:016lX})",
|
||||
static_cast<int>(Cop0::GetTLBExceptionCode(regs.cop0.tlbError, Cop0::LOAD)), static_cast<u64>(regs.pc));
|
||||
}
|
||||
|
||||
instruction = mem.Read<u32>(regs, paddr);
|
||||
@@ -56,10 +60,12 @@ int JIT::Step() {
|
||||
|
||||
pc += 4;
|
||||
|
||||
// Exec(instruction);
|
||||
Emit(instruction);
|
||||
}
|
||||
while (!InstrEndsBlock(instruction));
|
||||
|
||||
// emit code to store the value of pc
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
@@ -2,10 +2,23 @@
|
||||
#include <BaseCPU.hpp>
|
||||
#include <Mem.hpp>
|
||||
#include <vector>
|
||||
#include <xbyak.h>
|
||||
|
||||
namespace n64 {
|
||||
struct Core;
|
||||
|
||||
static constexpr u32 kAddressSpaceSize = 0x8000'0000; // >> 20 = 0x800
|
||||
static constexpr u32 kLowerSize = kAddressSpaceSize >> 20; // 0x800
|
||||
static constexpr u32 kUpperSize = 1 << 20; // 0x100000
|
||||
static constexpr u32 kCodeCacheSize = 32_mb;
|
||||
static constexpr u32 kCodeCacheAllocSize = kCodeCacheSize + 4096;
|
||||
|
||||
struct CodeGenerator : Xbyak::CodeGenerator {
|
||||
CodeGenerator() : Xbyak::CodeGenerator{kCodeCacheSize} {}
|
||||
};
|
||||
|
||||
enum BranchCondition { EQ, NE, GT, GE, LT, LE, GTU, GEU, LTU, LEU };
|
||||
|
||||
struct JIT : BaseCPU {
|
||||
explicit JIT(ParallelRDP &);
|
||||
~JIT() override = default;
|
||||
@@ -23,19 +36,21 @@ struct JIT : BaseCPU {
|
||||
[[nodiscard]] Disassembler::DisassemblyResult Disassemble(u32, u32) const override { return {}; }
|
||||
|
||||
private:
|
||||
CodeGenerator code;
|
||||
Registers regs;
|
||||
Mem mem;
|
||||
u64 cop2Latch{};
|
||||
friend struct Cop1;
|
||||
|
||||
#define check_address_error(mask, vaddr) \
|
||||
(((!regs.cop0.is64BitAddressing) && (s32)(vaddr) != (vaddr)) || (((vaddr) & (mask)) != 0))
|
||||
bool ShouldServiceInterrupt() const override;
|
||||
|
||||
[[nodiscard]] bool ShouldServiceInterrupt() const override;
|
||||
void CheckCompareInterrupt() override;
|
||||
std::vector<u8> Serialize() override;
|
||||
void Deserialize(const std::vector<u8> &) override;
|
||||
|
||||
void Emit(u32);
|
||||
void cop2Decode(u32);
|
||||
void special(u32);
|
||||
void regimm(u32);
|
||||
void add(u32);
|
||||
@@ -44,12 +59,14 @@ private:
|
||||
void addiu(u32);
|
||||
void andi(u32);
|
||||
void and_(u32);
|
||||
void branch(bool, s64);
|
||||
void branch_likely(bool, s64);
|
||||
void b(u32, bool);
|
||||
void blink(u32, bool);
|
||||
void bl(u32, bool);
|
||||
void bllink(u32, bool);
|
||||
void b(u32 instr, BranchCondition, u32 reg1, u32 reg2);
|
||||
void b(u32 instr, BranchCondition, u32 reg);
|
||||
void blink(u32 instr, BranchCondition, u32 reg1, u32 reg2);
|
||||
void blink(u32 instr, BranchCondition, u32 reg);
|
||||
void bl(u32 instr, BranchCondition, u32 reg1, u32 reg2);
|
||||
void bl(u32 instr, BranchCondition, u32 reg);
|
||||
void bllink(u32 instr, BranchCondition, u32 reg1, u32 reg2);
|
||||
void bllink(u32 instr, BranchCondition, u32 reg);
|
||||
void dadd(u32);
|
||||
void daddu(u32);
|
||||
void daddi(u32);
|
||||
@@ -79,6 +96,7 @@ private:
|
||||
void lbu(u32);
|
||||
void lb(u32);
|
||||
void ld(u32);
|
||||
void ldc1(u32);
|
||||
void ldl(u32);
|
||||
void ldr(u32);
|
||||
void lh(u32);
|
||||
@@ -86,6 +104,7 @@ private:
|
||||
void ll(u32);
|
||||
void lld(u32);
|
||||
void lw(u32);
|
||||
void lwc1(u32);
|
||||
void lwl(u32);
|
||||
void lwu(u32);
|
||||
void lwr(u32);
|
||||
@@ -100,6 +119,7 @@ private:
|
||||
void sc(u32);
|
||||
void scd(u32);
|
||||
void sd(u32);
|
||||
void sdc1(u32);
|
||||
void sdl(u32);
|
||||
void sdr(u32);
|
||||
void sh(u32);
|
||||
@@ -114,6 +134,7 @@ private:
|
||||
void sllv(u32);
|
||||
void sub(u32);
|
||||
void subu(u32);
|
||||
void swc1(u32);
|
||||
void sra(u32);
|
||||
void srav(u32);
|
||||
void srl(u32);
|
||||
@@ -123,12 +144,5 @@ private:
|
||||
void ori(u32);
|
||||
void xor_(u32);
|
||||
void xori(u32);
|
||||
|
||||
void mtc2(u32);
|
||||
void mfc2(u32);
|
||||
void dmtc2(u32);
|
||||
void dmfc2(u32);
|
||||
void ctc2(u32);
|
||||
void cfc2(u32);
|
||||
};
|
||||
} // namespace n64
|
||||
|
||||
388
src/backend/core/jit/decode.cpp
Normal file
388
src/backend/core/jit/decode.cpp
Normal file
@@ -0,0 +1,388 @@
|
||||
#include <JIT.hpp>
|
||||
#include <CpuDefinitions.hpp>
|
||||
|
||||
namespace n64 {
|
||||
void JIT::special(const u32 instr) {
|
||||
// 00rr_rccc
|
||||
switch (const u8 mask = instr & 0x3F) {
|
||||
case SLL:
|
||||
if (instr != 0) {
|
||||
sll(instr);
|
||||
}
|
||||
break;
|
||||
case SRL:
|
||||
srl(instr);
|
||||
break;
|
||||
case SRA:
|
||||
sra(instr);
|
||||
break;
|
||||
case SLLV:
|
||||
sllv(instr);
|
||||
break;
|
||||
case SRLV:
|
||||
srlv(instr);
|
||||
break;
|
||||
case SRAV:
|
||||
srav(instr);
|
||||
break;
|
||||
case JR:
|
||||
jr(instr);
|
||||
break;
|
||||
case JALR:
|
||||
jalr(instr);
|
||||
break;
|
||||
case SYSCALL:
|
||||
regs.cop0.FireException(ExceptionCode::Syscall, 0, regs.oldPC);
|
||||
break;
|
||||
case BREAK:
|
||||
regs.cop0.FireException(ExceptionCode::Breakpoint, 0, regs.oldPC);
|
||||
break;
|
||||
case SYNC:
|
||||
break; // SYNC
|
||||
case MFHI:
|
||||
mfhi(instr);
|
||||
break;
|
||||
case MTHI:
|
||||
mthi(instr);
|
||||
break;
|
||||
case MFLO:
|
||||
mflo(instr);
|
||||
break;
|
||||
case MTLO:
|
||||
mtlo(instr);
|
||||
break;
|
||||
case DSLLV:
|
||||
dsllv(instr);
|
||||
break;
|
||||
case DSRLV:
|
||||
dsrlv(instr);
|
||||
break;
|
||||
case DSRAV:
|
||||
dsrav(instr);
|
||||
break;
|
||||
case MULT:
|
||||
mult(instr);
|
||||
break;
|
||||
case MULTU:
|
||||
multu(instr);
|
||||
break;
|
||||
case DIV:
|
||||
div(instr);
|
||||
break;
|
||||
case DIVU:
|
||||
divu(instr);
|
||||
break;
|
||||
case DMULT:
|
||||
dmult(instr);
|
||||
break;
|
||||
case DMULTU:
|
||||
dmultu(instr);
|
||||
break;
|
||||
case DDIV:
|
||||
ddiv(instr);
|
||||
break;
|
||||
case DDIVU:
|
||||
ddivu(instr);
|
||||
break;
|
||||
case ADD:
|
||||
add(instr);
|
||||
break;
|
||||
case ADDU:
|
||||
addu(instr);
|
||||
break;
|
||||
case SUB:
|
||||
sub(instr);
|
||||
break;
|
||||
case SUBU:
|
||||
subu(instr);
|
||||
break;
|
||||
case AND:
|
||||
and_(instr);
|
||||
break;
|
||||
case OR:
|
||||
or_(instr);
|
||||
break;
|
||||
case XOR:
|
||||
xor_(instr);
|
||||
break;
|
||||
case NOR:
|
||||
nor(instr);
|
||||
break;
|
||||
case SLT:
|
||||
slt(instr);
|
||||
break;
|
||||
case SLTU:
|
||||
sltu(instr);
|
||||
break;
|
||||
case DADD:
|
||||
dadd(instr);
|
||||
break;
|
||||
case DADDU:
|
||||
daddu(instr);
|
||||
break;
|
||||
case DSUB:
|
||||
dsub(instr);
|
||||
break;
|
||||
case DSUBU:
|
||||
dsubu(instr);
|
||||
break;
|
||||
case TGE:
|
||||
trap(regs.Read<s64>(RS(instr)) >= regs.Read<s64>(RT(instr)));
|
||||
break;
|
||||
case TGEU:
|
||||
trap(regs.Read<u64>(RS(instr)) >= regs.Read<u64>(RT(instr)));
|
||||
break;
|
||||
case TLT:
|
||||
trap(regs.Read<s64>(RS(instr)) < regs.Read<s64>(RT(instr)));
|
||||
break;
|
||||
case TLTU:
|
||||
trap(regs.Read<u64>(RS(instr)) < regs.Read<u64>(RT(instr)));
|
||||
break;
|
||||
case TEQ:
|
||||
trap(regs.Read<s64>(RS(instr)) == regs.Read<s64>(RT(instr)));
|
||||
break;
|
||||
case TNE:
|
||||
trap(regs.Read<s64>(RS(instr)) != regs.Read<s64>(RT(instr)));
|
||||
break;
|
||||
case DSLL:
|
||||
dsll(instr);
|
||||
break;
|
||||
case DSRL:
|
||||
dsrl(instr);
|
||||
break;
|
||||
case DSRA:
|
||||
dsra(instr);
|
||||
break;
|
||||
case DSLL32:
|
||||
dsll32(instr);
|
||||
break;
|
||||
case DSRL32:
|
||||
dsrl32(instr);
|
||||
break;
|
||||
case DSRA32:
|
||||
dsra32(instr);
|
||||
break;
|
||||
default:
|
||||
Util::panic("Unimplemented special {} {} ({:08X}) (pc: {:016X})", (mask >> 3) & 7, mask & 7, instr,
|
||||
static_cast<u64>(regs.oldPC));
|
||||
}
|
||||
}
|
||||
|
||||
void JIT::regimm(const u32 instr) {
|
||||
// 000r_rccc
|
||||
switch (const u8 mask = instr >> 16 & 0x1F) {
|
||||
case BLTZ:
|
||||
b(instr, LT, RS(instr));
|
||||
break;
|
||||
case BGEZ:
|
||||
b(instr, GE, RS(instr));
|
||||
break;
|
||||
case BLTZL:
|
||||
bl(instr, LT, RS(instr));
|
||||
break;
|
||||
case BGEZL:
|
||||
bl(instr, GE, RS(instr));
|
||||
break;
|
||||
case TGEI:
|
||||
trap(regs.Read<s64>(RS(instr)) >= static_cast<s64>(static_cast<s16>(instr)));
|
||||
break;
|
||||
case TGEIU:
|
||||
trap(regs.Read<u64>(RS(instr)) >= static_cast<u64>(static_cast<s64>(static_cast<s16>(instr))));
|
||||
break;
|
||||
case TLTI:
|
||||
trap(regs.Read<s64>(RS(instr)) < static_cast<s64>(static_cast<s16>(instr)));
|
||||
break;
|
||||
case TLTIU:
|
||||
trap(regs.Read<u64>(RS(instr)) < static_cast<u64>(static_cast<s64>(static_cast<s16>(instr))));
|
||||
break;
|
||||
case TEQI:
|
||||
trap(regs.Read<s64>(RS(instr)) == static_cast<s64>(static_cast<s16>(instr)));
|
||||
break;
|
||||
case TNEI:
|
||||
trap(regs.Read<s64>(RS(instr)) != static_cast<s64>(static_cast<s16>(instr)));
|
||||
break;
|
||||
case BLTZAL:
|
||||
blink(instr, LT, RS(instr));
|
||||
break;
|
||||
case BGEZAL:
|
||||
blink(instr, GE, RS(instr));
|
||||
break;
|
||||
case BLTZALL:
|
||||
bllink(instr, LT, RS(instr));
|
||||
break;
|
||||
case BGEZALL:
|
||||
bllink(instr, GE, RS(instr));
|
||||
break;
|
||||
default:
|
||||
Util::panic("Unimplemented regimm {} {} ({:08X}) (pc: {:016X})", (mask >> 3) & 3, mask & 7, instr,
|
||||
static_cast<u64>(regs.oldPC));
|
||||
}
|
||||
}
|
||||
|
||||
void JIT::Emit(const u32 instr) {
|
||||
switch (const u8 mask = instr >> 26 & 0x3f) {
|
||||
case SPECIAL:
|
||||
special(instr);
|
||||
break;
|
||||
case REGIMM:
|
||||
regimm(instr);
|
||||
break;
|
||||
case J:
|
||||
j(instr);
|
||||
break;
|
||||
case JAL:
|
||||
jal(instr);
|
||||
break;
|
||||
case BEQ:
|
||||
b(instr, EQ, RS(instr), RT(instr));
|
||||
break;
|
||||
case BNE:
|
||||
b(instr, NE, RS(instr), RT(instr));
|
||||
break;
|
||||
case BLEZ:
|
||||
b(instr, LE, RS(instr));
|
||||
break;
|
||||
case BGTZ:
|
||||
b(instr, GT, RS(instr));
|
||||
break;
|
||||
case ADDI:
|
||||
addi(instr);
|
||||
break;
|
||||
case ADDIU:
|
||||
addiu(instr);
|
||||
break;
|
||||
case SLTI:
|
||||
slti(instr);
|
||||
break;
|
||||
case SLTIU:
|
||||
sltiu(instr);
|
||||
break;
|
||||
case ANDI:
|
||||
andi(instr);
|
||||
break;
|
||||
case ORI:
|
||||
ori(instr);
|
||||
break;
|
||||
case XORI:
|
||||
xori(instr);
|
||||
break;
|
||||
case LUI:
|
||||
lui(instr);
|
||||
break;
|
||||
case COP0:
|
||||
regs.cop0.decode(*this, instr);
|
||||
break;
|
||||
case COP1:
|
||||
regs.cop1.decode(*this, instr);
|
||||
break;
|
||||
case COP2:
|
||||
break;
|
||||
case BEQL:
|
||||
bl(instr, EQ, RS(instr), RT(instr));
|
||||
break;
|
||||
case BNEL:
|
||||
bl(instr, NE, RS(instr), RT(instr));
|
||||
break;
|
||||
case BLEZL:
|
||||
bl(instr, LE, RS(instr));
|
||||
break;
|
||||
case BGTZL:
|
||||
bl(instr, GT, RS(instr));
|
||||
break;
|
||||
case DADDI:
|
||||
daddi(instr);
|
||||
break;
|
||||
case DADDIU:
|
||||
daddiu(instr);
|
||||
break;
|
||||
case LDL:
|
||||
ldl(instr);
|
||||
break;
|
||||
case LDR:
|
||||
ldr(instr);
|
||||
break;
|
||||
case 0x1F:
|
||||
regs.cop0.FireException(ExceptionCode::ReservedInstruction, 0, regs.oldPC);
|
||||
break;
|
||||
case LB:
|
||||
lb(instr);
|
||||
break;
|
||||
case LH:
|
||||
lh(instr);
|
||||
break;
|
||||
case LWL:
|
||||
lwl(instr);
|
||||
break;
|
||||
case LW:
|
||||
lw(instr);
|
||||
break;
|
||||
case LBU:
|
||||
lbu(instr);
|
||||
break;
|
||||
case LHU:
|
||||
lhu(instr);
|
||||
break;
|
||||
case LWR:
|
||||
lwr(instr);
|
||||
break;
|
||||
case LWU:
|
||||
lwu(instr);
|
||||
break;
|
||||
case SB:
|
||||
sb(instr);
|
||||
break;
|
||||
case SH:
|
||||
sh(instr);
|
||||
break;
|
||||
case SWL:
|
||||
swl(instr);
|
||||
break;
|
||||
case SW:
|
||||
sw(instr);
|
||||
break;
|
||||
case SDL:
|
||||
sdl(instr);
|
||||
break;
|
||||
case SDR:
|
||||
sdr(instr);
|
||||
break;
|
||||
case SWR:
|
||||
swr(instr);
|
||||
break;
|
||||
case CACHE:
|
||||
break; // CACHE
|
||||
case LL:
|
||||
ll(instr);
|
||||
break;
|
||||
case LWC1:
|
||||
lwc1(instr);
|
||||
break;
|
||||
case LLD:
|
||||
lld(instr);
|
||||
break;
|
||||
case LDC1:
|
||||
ldc1(instr);
|
||||
break;
|
||||
case LD:
|
||||
ld(instr);
|
||||
break;
|
||||
case SC:
|
||||
sc(instr);
|
||||
break;
|
||||
case SWC1:
|
||||
swc1(instr);
|
||||
break;
|
||||
case SCD:
|
||||
scd(instr);
|
||||
break;
|
||||
case SDC1:
|
||||
sdc1(instr);
|
||||
break;
|
||||
case SD:
|
||||
sd(instr);
|
||||
break;
|
||||
default:
|
||||
Util::panic("Unimplemented instruction {:02X} ({:08X}) (pc: {:016X})", mask, instr, static_cast<u64>(regs.oldPC));
|
||||
}
|
||||
}
|
||||
} // namespace n64
|
||||
@@ -1,9 +1,9 @@
|
||||
#pragma once
|
||||
#include <CpuDefinitions.hpp>
|
||||
|
||||
namespace n64 {
|
||||
static inline bool SpecialEndsBlock(u32 instr) {
|
||||
u8 mask = instr & 0x3F;
|
||||
switch (mask) {
|
||||
static bool SpecialEndsBlock(const u32 instr) {
|
||||
switch (instr & 0x3F) {
|
||||
case JR:
|
||||
case JALR:
|
||||
case SYSCALL:
|
||||
@@ -20,9 +20,8 @@ static inline bool SpecialEndsBlock(u32 instr) {
|
||||
}
|
||||
}
|
||||
|
||||
static inline bool InstrEndsBlock(u32 instr) {
|
||||
u8 mask = (instr >> 26) & 0x3f;
|
||||
switch (mask) {
|
||||
static bool InstrEndsBlock(const u32 instr) {
|
||||
switch (instr >> 26 & 0x3f) {
|
||||
case SPECIAL:
|
||||
return SpecialEndsBlock(instr);
|
||||
case REGIMM:
|
||||
|
||||
@@ -79,6 +79,75 @@ void JIT::and_(u32 instr) {
|
||||
}
|
||||
}
|
||||
|
||||
void branch(Registers ®s, const bool cond, const s64 address) {
|
||||
regs.delaySlot = true;
|
||||
if (cond) {
|
||||
regs.nextPC = address;
|
||||
}
|
||||
}
|
||||
|
||||
void branch_likely(Registers ®s, const bool cond, const s64 address) {
|
||||
if (cond) {
|
||||
regs.delaySlot = true;
|
||||
regs.nextPC = address;
|
||||
} else {
|
||||
regs.SetPC64(regs.nextPC);
|
||||
}
|
||||
}
|
||||
|
||||
bool EvaluateCondition(Registers ®s, BranchCondition, u32, u32) {
|
||||
Util::panic("[JIT]: non-constant EvaluateCondition!");
|
||||
}
|
||||
|
||||
bool EvaluateConditionConstant(Registers ®s, const BranchCondition cond, const u32 reg1, const u32 reg2) {
|
||||
switch (cond) {
|
||||
case EQ:
|
||||
return regs.Read<s64>(reg1) == regs.Read<s64>(reg2);
|
||||
case NE:
|
||||
return regs.Read<s64>(reg1) != regs.Read<s64>(reg2);
|
||||
case LT:
|
||||
return regs.Read<s64>(reg1) < regs.Read<s64>(reg2);
|
||||
case LE:
|
||||
return regs.Read<s64>(reg1) <= regs.Read<s64>(reg2);
|
||||
case GT:
|
||||
return regs.Read<s64>(reg1) > regs.Read<s64>(reg2);
|
||||
case GE:
|
||||
return regs.Read<s64>(reg1) >= regs.Read<s64>(reg2);
|
||||
case LTU:
|
||||
return regs.Read<u64>(reg1) < regs.Read<u64>(reg2);
|
||||
case LEU:
|
||||
return regs.Read<u64>(reg1) <= regs.Read<u64>(reg2);
|
||||
case GTU:
|
||||
return regs.Read<u64>(reg1) > regs.Read<u64>(reg2);
|
||||
case GEU:
|
||||
return regs.Read<u64>(reg1) >= regs.Read<u64>(reg2);
|
||||
}
|
||||
}
|
||||
|
||||
void JIT::b(u32 instr, BranchCondition cond, u32 reg1, u32 reg2) {
|
||||
bool isConstant = regs.IsRegConstant(reg1, reg2);
|
||||
if (isConstant) {
|
||||
const s16 imm = instr;
|
||||
const s64 offset = u64((s64)imm) << 2;
|
||||
const s64 address = regs.pc + offset;
|
||||
branch(regs, EvaluateConditionConstant(regs, cond, reg1, reg2), address);
|
||||
}
|
||||
}
|
||||
|
||||
void JIT::b(u32 instr, BranchCondition cond, u32 reg) {}
|
||||
|
||||
void JIT::blink(u32 instr, BranchCondition cond, u32 reg1, u32 reg2) {}
|
||||
|
||||
void JIT::blink(u32 instr, BranchCondition cond, u32 reg) {}
|
||||
|
||||
void JIT::bl(u32 instr, BranchCondition cond, u32 reg1, u32 reg2) {}
|
||||
|
||||
void JIT::bl(u32 instr, BranchCondition cond, u32 reg) {}
|
||||
|
||||
void JIT::bllink(u32 instr, BranchCondition cond, u32 reg1, u32 reg2) {}
|
||||
|
||||
void JIT::bllink(u32 instr, BranchCondition cond, u32 reg) {}
|
||||
|
||||
void JIT::dadd(u32 instr) {
|
||||
if (regs.IsRegConstant(RS(instr), RT(instr))) {
|
||||
auto rs = regs.Read<u64>(RS(instr));
|
||||
|
||||
@@ -85,8 +85,6 @@ union FCR31 {
|
||||
}
|
||||
};
|
||||
|
||||
enum CompConds { F, UN, EQ, UEQ, OLT, ULT, OLE, ULE, SF, NGLE, SEQ, NGL, LT, NGE, LE, NGT };
|
||||
|
||||
union FloatingPointReg {
|
||||
struct {
|
||||
s32 int32;
|
||||
|
||||
Reference in New Issue
Block a user