Optimizations (are they?)
This commit is contained in:
@@ -22,8 +22,6 @@ inline void CheckCompareInterrupt(MI& mi, Registers& regs) {
|
||||
}
|
||||
|
||||
void Interpreter::Step(Mem& mem) {
|
||||
regs.gpr[0] = 0;
|
||||
|
||||
CheckCompareInterrupt(mem.mmio.mi, regs);
|
||||
|
||||
regs.prevDelaySlot = regs.delaySlot;
|
||||
|
||||
@@ -12,10 +12,8 @@ Mem::Mem() {
|
||||
}
|
||||
|
||||
void Mem::Reset() {
|
||||
readPages.resize(PAGE_COUNT);
|
||||
writePages.resize(PAGE_COUNT);
|
||||
std::fill(readPages.begin(), readPages.end(), 0);
|
||||
std::fill(writePages.begin(), writePages.end(), 0);
|
||||
memset(readPages, 0, PAGE_COUNT);
|
||||
memset(writePages, 0, PAGE_COUNT);
|
||||
|
||||
for(int i = 0; i < RDRAM_SIZE / PAGE_SIZE; i++) {
|
||||
const auto addr = (i * PAGE_SIZE) & RDRAM_DSIZE;
|
||||
@@ -24,9 +22,16 @@ void Mem::Reset() {
|
||||
writePages[i] = pointer;
|
||||
}
|
||||
|
||||
sram.resize(SRAM_SIZE);
|
||||
std::fill(sram.begin(), sram.end(), 0);
|
||||
romMask = 0;
|
||||
if(sram) {
|
||||
free(sram);
|
||||
}
|
||||
|
||||
if(cart) {
|
||||
free(cart);
|
||||
}
|
||||
|
||||
cart = (u8*)calloc(CART_SIZE, 1);
|
||||
sram = (u8*)calloc(SRAM_SIZE, 1);
|
||||
mmio.Reset();
|
||||
}
|
||||
|
||||
@@ -39,22 +44,20 @@ CartInfo Mem::LoadROM(const std::string& filename) {
|
||||
}
|
||||
|
||||
file.seekg(0, std::ios::end);
|
||||
auto size = file.tellg();
|
||||
auto sizeAdjusted = Util::NextPow2(size);
|
||||
size_t size = file.tellg();
|
||||
size_t sizeAdjusted = Util::NextPow2(size);
|
||||
romMask = sizeAdjusted - 1;
|
||||
file.seekg(0, std::ios::beg);
|
||||
|
||||
std::fill(cart.begin(), cart.end(), 0);
|
||||
cart.resize(sizeAdjusted);
|
||||
cart.insert(cart.begin(), std::istream_iterator<u8>(file), std::istream_iterator<u8>());
|
||||
file.read(reinterpret_cast<char*>(cart), size);
|
||||
|
||||
file.close();
|
||||
|
||||
CartInfo result{};
|
||||
|
||||
u32 cicChecksum;
|
||||
Util::SwapN64Rom(sizeAdjusted, cart.data(), result.crc, cicChecksum);
|
||||
memcpy(mmio.rsp.dmem, cart.data(), 0x1000);
|
||||
Util::SwapN64Rom(sizeAdjusted, cart, result.crc, cicChecksum);
|
||||
memcpy(mmio.rsp.dmem, cart, 0x1000);
|
||||
|
||||
SetCICType(result.cicType, cicChecksum);
|
||||
result.isPAL = IsROMPAL();
|
||||
@@ -108,13 +111,13 @@ u8 Mem::Read8(n64::Registers ®s, u32 paddr) {
|
||||
int offs = 3 - (paddr & 3);
|
||||
return (w >> (offs * 8)) & 0xff;
|
||||
}
|
||||
case 0x10000000 ... 0x1FBFFFFF:
|
||||
case CART_REGION:
|
||||
paddr = (paddr + 2) & ~2;
|
||||
return cart[BYTE_ADDRESS(paddr) & romMask];
|
||||
case 0x1FC00000 ... 0x1FC007BF:
|
||||
return pifBootrom[BYTE_ADDRESS(paddr) - 0x1FC00000];
|
||||
case 0x1FC007C0 ... 0x1FC007FF:
|
||||
return pifRam[paddr - 0x1FC007C0];
|
||||
case PIF_RAM_REGION:
|
||||
return pifRam[paddr - PIF_RAM_REGION_START];
|
||||
case 0x00800000 ... 0x03FFFFFF:
|
||||
case 0x04200000 ... 0x042FFFFF:
|
||||
case 0x04900000 ... 0x0FFFFFFF:
|
||||
@@ -136,7 +139,7 @@ u16 Mem::Read16(n64::Registers ®s, u32 paddr) {
|
||||
} else {
|
||||
switch (paddr) {
|
||||
case 0x00000000 ... 0x007FFFFF:
|
||||
return Util::ReadAccess<u16>(mmio.rdp.rdram.data(), HALF_ADDRESS(paddr));
|
||||
return Util::ReadAccess<u16>(mmio.rdp.rdram, HALF_ADDRESS(paddr));
|
||||
case 0x04000000 ... 0x0403FFFF:
|
||||
if (paddr & 0x1000)
|
||||
return Util::ReadAccess<u16>(mmio.rsp.imem, HALF_ADDRESS(paddr) & IMEM_DSIZE);
|
||||
@@ -149,11 +152,11 @@ u16 Mem::Read16(n64::Registers ®s, u32 paddr) {
|
||||
return mmio.Read(paddr);
|
||||
case 0x10000000 ... 0x1FBFFFFF:
|
||||
paddr = (paddr + 2) & ~3;
|
||||
return Util::ReadAccess<u16>(cart.data(), HALF_ADDRESS(paddr) & romMask);
|
||||
return Util::ReadAccess<u16>(cart, HALF_ADDRESS(paddr) & romMask);
|
||||
case 0x1FC00000 ... 0x1FC007BF:
|
||||
return Util::ReadAccess<u16>(pifBootrom, HALF_ADDRESS(paddr) - 0x1FC00000);
|
||||
case 0x1FC007C0 ... 0x1FC007FF:
|
||||
return be16toh(Util::ReadAccess<u16>(pifRam, paddr - 0x1FC007C0));
|
||||
case PIF_RAM_REGION:
|
||||
return be16toh(Util::ReadAccess<u16>(pifRam, paddr - PIF_RAM_REGION_START));
|
||||
case 0x00800000 ... 0x03FFFFFF:
|
||||
case 0x04200000 ... 0x042FFFFF:
|
||||
case 0x04900000 ... 0x0FFFFFFF:
|
||||
@@ -175,7 +178,7 @@ u32 Mem::Read32(n64::Registers ®s, u32 paddr) {
|
||||
} else {
|
||||
switch(paddr) {
|
||||
case 0x00000000 ... 0x007FFFFF:
|
||||
return Util::ReadAccess<u32>(mmio.rdp.rdram.data(), paddr);
|
||||
return Util::ReadAccess<u32>(mmio.rdp.rdram, paddr);
|
||||
case 0x04000000 ... 0x0403FFFF:
|
||||
if(paddr & 0x1000)
|
||||
return Util::ReadAccess<u32>(mmio.rsp.imem, paddr & IMEM_DSIZE);
|
||||
@@ -185,11 +188,11 @@ u32 Mem::Read32(n64::Registers ®s, u32 paddr) {
|
||||
case 0x04300000 ... 0x044FFFFF: case 0x04500000 ... 0x048FFFFF:
|
||||
return mmio.Read(paddr);
|
||||
case 0x10000000 ... 0x1FBFFFFF:
|
||||
return Util::ReadAccess<u32>(cart.data(), paddr & romMask);
|
||||
return Util::ReadAccess<u32>(cart, paddr & romMask);
|
||||
case 0x1FC00000 ... 0x1FC007BF:
|
||||
return Util::ReadAccess<u32>(pifBootrom, paddr - 0x1FC00000);
|
||||
case 0x1FC007C0 ... 0x1FC007FF:
|
||||
return be32toh(Util::ReadAccess<u32>(pifRam, paddr - 0x1FC007C0));
|
||||
case PIF_RAM_REGION:
|
||||
return be32toh(Util::ReadAccess<u32>(pifRam, paddr - PIF_RAM_REGION_START));
|
||||
case 0x00800000 ... 0x03FFFFFF: case 0x04200000 ... 0x042FFFFF:
|
||||
case 0x04900000 ... 0x0FFFFFFF: case 0x1FC00800 ... 0xFFFFFFFF: return 0;
|
||||
default:
|
||||
@@ -208,7 +211,7 @@ u64 Mem::Read64(n64::Registers ®s, u32 paddr) {
|
||||
} else {
|
||||
switch (paddr) {
|
||||
case 0x00000000 ... 0x007FFFFF:
|
||||
return Util::ReadAccess<u64>(mmio.rdp.rdram.data(), paddr);
|
||||
return Util::ReadAccess<u64>(mmio.rdp.rdram, paddr);
|
||||
case 0x04000000 ... 0x0403FFFF:
|
||||
if (paddr & 0x1000)
|
||||
return Util::ReadAccess<u64>(mmio.rsp.imem, paddr & IMEM_DSIZE);
|
||||
@@ -220,11 +223,11 @@ u64 Mem::Read64(n64::Registers ®s, u32 paddr) {
|
||||
case 0x04500000 ... 0x048FFFFF:
|
||||
return mmio.Read(paddr);
|
||||
case 0x10000000 ... 0x1FBFFFFF:
|
||||
return Util::ReadAccess<u64>(cart.data(), paddr & romMask);
|
||||
return Util::ReadAccess<u64>(cart, paddr & romMask);
|
||||
case 0x1FC00000 ... 0x1FC007BF:
|
||||
return Util::ReadAccess<u64>(pifBootrom, paddr - 0x1FC00000);
|
||||
case 0x1FC007C0 ... 0x1FC007FF:
|
||||
return be64toh(Util::ReadAccess<u64>(pifRam, paddr - 0x1FC007C0));
|
||||
case PIF_RAM_REGION:
|
||||
return be64toh(Util::ReadAccess<u64>(pifRam, paddr - PIF_RAM_REGION_START));
|
||||
case 0x00800000 ... 0x03FFFFFF:
|
||||
case 0x04200000 ... 0x042FFFFF:
|
||||
case 0x04900000 ... 0x0FFFFFFF:
|
||||
@@ -283,9 +286,9 @@ void Mem::Write8(Registers& regs, u32 paddr, u32 val) {
|
||||
Util::panic("MMIO Write8!\n");
|
||||
case 0x10000000 ... 0x1FBFFFFF:
|
||||
break;
|
||||
case 0x1FC007C0 ... 0x1FC007FF:
|
||||
case PIF_RAM_REGION:
|
||||
val = val << (8 * (3 - (paddr & 3)));
|
||||
paddr = (paddr - 0x1FC007C0) & ~3;
|
||||
paddr = (paddr - PIF_RAM_REGION_START) & ~3;
|
||||
Util::WriteAccess<u32>(pifRam, paddr, htobe32(val));
|
||||
ProcessPIFCommands(pifRam, mmio.si.controller, *this);
|
||||
break;
|
||||
@@ -317,7 +320,7 @@ void Mem::Write16(Registers& regs, u32 paddr, u32 val) {
|
||||
} else {
|
||||
switch (paddr) {
|
||||
case 0x00000000 ... 0x007FFFFF:
|
||||
Util::WriteAccess<u16>(mmio.rdp.rdram.data(), HALF_ADDRESS(paddr), val);
|
||||
Util::WriteAccess<u16>(mmio.rdp.rdram, HALF_ADDRESS(paddr), val);
|
||||
break;
|
||||
case 0x04000000 ... 0x0403FFFF:
|
||||
val = val << (16 * !(paddr & 2));
|
||||
@@ -334,10 +337,10 @@ void Mem::Write16(Registers& regs, u32 paddr, u32 val) {
|
||||
Util::panic("MMIO Write16!\n");
|
||||
case 0x10000000 ... 0x1FBFFFFF:
|
||||
break;
|
||||
case 0x1FC007C0 ... 0x1FC007FF:
|
||||
case PIF_RAM_REGION:
|
||||
val = val << (16 * !(paddr & 2));
|
||||
paddr &= ~3;
|
||||
Util::WriteAccess<u32>(pifRam, paddr - 0x1FC007C0, htobe32(val));
|
||||
Util::WriteAccess<u32>(pifRam, paddr - PIF_RAM_REGION_START, htobe32(val));
|
||||
ProcessPIFCommands(pifRam, mmio.si.controller, *this);
|
||||
break;
|
||||
case 0x00800000 ... 0x03FFFFFF:
|
||||
@@ -364,7 +367,7 @@ void Mem::Write32(Registers& regs, u32 paddr, u32 val) {
|
||||
} else {
|
||||
switch(paddr) {
|
||||
case 0x00000000 ... 0x007FFFFF:
|
||||
Util::WriteAccess<u32>(mmio.rdp.rdram.data(), paddr, val);
|
||||
Util::WriteAccess<u32>(mmio.rdp.rdram, paddr, val);
|
||||
break;
|
||||
case 0x04000000 ... 0x0403FFFF:
|
||||
if(paddr & 0x1000)
|
||||
@@ -387,8 +390,8 @@ void Mem::Write32(Registers& regs, u32 paddr, u32 val) {
|
||||
Util::WriteAccess<u32>(isviewer, paddr - 0x13FF0020, htobe32(val));
|
||||
break;
|
||||
case 0x14000000 ... 0x1FBFFFFF: break;
|
||||
case 0x1FC007C0 ... 0x1FC007FF:
|
||||
Util::WriteAccess<u32>(pifRam, paddr - 0x1FC007C0, htobe32(val));
|
||||
case PIF_RAM_REGION:
|
||||
Util::WriteAccess<u32>(pifRam, paddr - PIF_RAM_REGION_START, htobe32(val));
|
||||
ProcessPIFCommands(pifRam, mmio.si.controller, *this);
|
||||
break;
|
||||
case 0x00800000 ... 0x03FFFFFF: case 0x04200000 ... 0x042FFFFF:
|
||||
@@ -409,7 +412,7 @@ void Mem::Write64(Registers& regs, u32 paddr, u64 val) {
|
||||
} else {
|
||||
switch (paddr) {
|
||||
case 0x00000000 ... 0x007FFFFF:
|
||||
Util::WriteAccess<u64>(mmio.rdp.rdram.data(), paddr, val);
|
||||
Util::WriteAccess<u64>(mmio.rdp.rdram, paddr, val);
|
||||
break;
|
||||
case 0x04000000 ... 0x0403FFFF:
|
||||
val >>= 32;
|
||||
@@ -425,8 +428,8 @@ void Mem::Write64(Registers& regs, u32 paddr, u64 val) {
|
||||
Util::panic("MMIO Write64!\n");
|
||||
case 0x10000000 ... 0x1FBFFFFF:
|
||||
break;
|
||||
case 0x1FC007C0 ... 0x1FC007FF:
|
||||
Util::WriteAccess<u64>(pifRam, paddr - 0x1FC007C0, htobe64(val));
|
||||
case PIF_RAM_REGION:
|
||||
Util::WriteAccess<u64>(pifRam, paddr - PIF_RAM_REGION_START, htobe64(val));
|
||||
ProcessPIFCommands(pifRam, mmio.si.controller, *this);
|
||||
break;
|
||||
case 0x00800000 ... 0x03FFFFFF:
|
||||
|
||||
@@ -5,10 +5,10 @@
|
||||
#include <vector>
|
||||
#include <backend/RomHelpers.hpp>
|
||||
#include <log.hpp>
|
||||
#include <Registers.hpp>
|
||||
#include <algorithm>
|
||||
|
||||
namespace n64 {
|
||||
struct Registers;
|
||||
|
||||
struct CartInfo {
|
||||
bool isPAL;
|
||||
u32 cicType;
|
||||
@@ -20,12 +20,14 @@ struct Dynarec;
|
||||
}
|
||||
|
||||
struct Mem {
|
||||
~Mem() = default;
|
||||
~Mem() {
|
||||
free(sram);
|
||||
}
|
||||
Mem();
|
||||
void Reset();
|
||||
CartInfo LoadROM(const std::string&);
|
||||
[[nodiscard]] auto GetRDRAM() -> u8* {
|
||||
return mmio.rdp.rdram.data();
|
||||
[[nodiscard]] auto GetRDRAM() const -> u8* {
|
||||
return mmio.rdp.rdram;
|
||||
}
|
||||
|
||||
u8 Read8(Registers&, u32);
|
||||
@@ -47,7 +49,7 @@ struct Mem {
|
||||
inline void DumpRDRAM() const {
|
||||
FILE *fp = fopen("rdram.dump", "wb");
|
||||
u8 *temp = (u8*)calloc(RDRAM_SIZE, 1);
|
||||
memcpy(temp, mmio.rdp.rdram.data(), RDRAM_SIZE);
|
||||
memcpy(temp, mmio.rdp.rdram, RDRAM_SIZE);
|
||||
Util::SwapBuffer32(RDRAM_SIZE, temp);
|
||||
fwrite(temp, 1, RDRAM_SIZE, fp);
|
||||
free(temp);
|
||||
@@ -73,20 +75,19 @@ struct Mem {
|
||||
free(temp);
|
||||
fclose(fp);
|
||||
}
|
||||
std::vector<uintptr_t> writePages, readPages;
|
||||
uintptr_t writePages[PAGE_COUNT], readPages[PAGE_COUNT];
|
||||
private:
|
||||
friend struct SI;
|
||||
friend struct PI;
|
||||
friend struct AI;
|
||||
friend struct Cpu;
|
||||
friend struct RSP;
|
||||
friend struct Core;
|
||||
std::vector<u8> cart, sram;
|
||||
u8* sram, *cart;
|
||||
u8 pifBootrom[PIF_BOOTROM_SIZE]{};
|
||||
u8 isviewer[ISVIEWER_SIZE]{};
|
||||
size_t romMask;
|
||||
size_t romMask = 0;
|
||||
|
||||
void SetCICType(u32& cicType, u32 checksum) {
|
||||
static void SetCICType(u32& cicType, u32 checksum) {
|
||||
switch(checksum) {
|
||||
case 0xEC8B1325: // 7102
|
||||
cicType = CIC_NUS_7102;
|
||||
@@ -115,12 +116,15 @@ private:
|
||||
|
||||
bool IsROMPAL() {
|
||||
static const char pal_codes[] = {'D', 'F', 'I', 'P', 'S', 'U', 'X', 'Y'};
|
||||
for (int i = 0; i < 8; i++) {
|
||||
if (cart[0x3e] == pal_codes[i]) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
return std::any_of(std::begin(pal_codes), std::end(pal_codes), [this](char a) {
|
||||
return cart[0x3e] == a;
|
||||
});
|
||||
// for (char pal_code : pal_codes) {
|
||||
// if (cart[0x3e] == pal_code) {
|
||||
// return true;
|
||||
// }
|
||||
// }
|
||||
// return false;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
@@ -11,8 +11,10 @@ RDP::RDP() {
|
||||
|
||||
void RDP::Reset() {
|
||||
dpc.status.raw = 0x80;
|
||||
rdram.resize(RDRAM_SIZE);
|
||||
std::fill(rdram.begin(), rdram.end(), 0);
|
||||
if(rdram) {
|
||||
free(rdram);
|
||||
}
|
||||
rdram = (u8*)calloc(RDRAM_SIZE, 1);
|
||||
memset(cmd_buf, 0, 0x100000);
|
||||
}
|
||||
|
||||
@@ -144,7 +146,7 @@ void RDP::RunCommand(MI& mi, Registers& regs, RSP& rsp) {
|
||||
return;
|
||||
}
|
||||
for (int i = 0; i < len; i += 4) {
|
||||
u32 cmd = Util::ReadAccess<u32>(rdram.data(), current + i);
|
||||
u32 cmd = Util::ReadAccess<u32>(rdram, current + i);
|
||||
cmd_buf[remaining_cmds + (i >> 2)] = cmd;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -57,7 +57,7 @@ struct RDP {
|
||||
RDP();
|
||||
void Reset();
|
||||
|
||||
std::vector<u8> rdram;
|
||||
u8* rdram;
|
||||
[[nodiscard]] auto Read(u32 addr) const -> u32;
|
||||
void Write(MI& mi, Registers& regs, RSP& rsp, u32 addr, u32 val);
|
||||
void WriteStatus(MI& mi, Registers& regs, RSP& rsp, u32 val);
|
||||
|
||||
@@ -13,15 +13,19 @@ void add(Registers& regs, u32 instr) {
|
||||
if(check_signed_overflow(rs, rt, result)) {
|
||||
FireException(regs, ExceptionCode::Overflow, 0, true);
|
||||
} else {
|
||||
regs.gpr[RD(instr)] = s32(result);
|
||||
if(likely(RD(instr) != 0)) {
|
||||
regs.gpr[RD(instr)] = s32(result);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void addu(Registers& regs, u32 instr) {
|
||||
s32 rs = (s32)regs.gpr[RS(instr)];
|
||||
s32 rt = (s32)regs.gpr[RT(instr)];
|
||||
s32 result = rs + rt;
|
||||
regs.gpr[RD(instr)] = result;
|
||||
if(likely(RD(instr) != 0)) {
|
||||
s32 rs = (s32)regs.gpr[RS(instr)];
|
||||
s32 rt = (s32)regs.gpr[RT(instr)];
|
||||
s32 result = rs + rt;
|
||||
regs.gpr[RD(instr)] = result;
|
||||
}
|
||||
}
|
||||
|
||||
void addi(Registers& regs, u32 instr) {
|
||||
@@ -49,14 +53,18 @@ void dadd(Registers& regs, u32 instr) {
|
||||
if(check_signed_overflow(rs, rt, result)) {
|
||||
FireException(regs, ExceptionCode::Overflow, 0, true);
|
||||
} else {
|
||||
regs.gpr[RD(instr)] = result;
|
||||
if(likely(RD(instr) != 0)) {
|
||||
regs.gpr[RD(instr)] = result;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void daddu(Registers& regs, u32 instr) {
|
||||
s64 rs = regs.gpr[RS(instr)];
|
||||
s64 rt = regs.gpr[RT(instr)];
|
||||
regs.gpr[RD(instr)] = rs + rt;
|
||||
if(likely(RD(instr) != 0)) {
|
||||
s64 rs = regs.gpr[RS(instr)];
|
||||
s64 rt = regs.gpr[RT(instr)];
|
||||
regs.gpr[RD(instr)] = rs + rt;
|
||||
}
|
||||
}
|
||||
|
||||
void daddi(Registers& regs, u32 instr) {
|
||||
@@ -545,11 +553,15 @@ void ori(Registers& regs, u32 instr) {
|
||||
}
|
||||
|
||||
void or_(Registers& regs, u32 instr) {
|
||||
regs.gpr[RD(instr)] = regs.gpr[RS(instr)] | regs.gpr[RT(instr)];
|
||||
if(likely(RD(instr) != 0)) {
|
||||
regs.gpr[RD(instr)] = regs.gpr[RS(instr)] | regs.gpr[RT(instr)];
|
||||
}
|
||||
}
|
||||
|
||||
void nor(Registers& regs, u32 instr) {
|
||||
regs.gpr[RD(instr)] = ~(regs.gpr[RS(instr)] | regs.gpr[RT(instr)]);
|
||||
if(likely(RD(instr) != 0)) {
|
||||
regs.gpr[RD(instr)] = ~(regs.gpr[RS(instr)] | regs.gpr[RT(instr)]);
|
||||
}
|
||||
}
|
||||
|
||||
void j(Registers& regs, u32 instr) {
|
||||
@@ -566,7 +578,9 @@ void jal(Registers& regs, u32 instr) {
|
||||
|
||||
void jalr(Registers& regs, u32 instr) {
|
||||
branch(regs, true, regs.gpr[RS(instr)]);
|
||||
regs.gpr[RD(instr)] = regs.pc + 4;
|
||||
if(likely(RD(instr) != 0)) {
|
||||
regs.gpr[RD(instr)] = regs.pc + 4;
|
||||
}
|
||||
}
|
||||
|
||||
void slti(Registers& regs, u32 instr) {
|
||||
@@ -578,11 +592,15 @@ void sltiu(Registers& regs, u32 instr) {
|
||||
}
|
||||
|
||||
void slt(Registers& regs, u32 instr) {
|
||||
regs.gpr[RD(instr)] = regs.gpr[RS(instr)] < regs.gpr[RT(instr)];
|
||||
if(likely(RD(instr) != 0)) {
|
||||
regs.gpr[RD(instr)] = regs.gpr[RS(instr)] < regs.gpr[RT(instr)];
|
||||
}
|
||||
}
|
||||
|
||||
void sltu(Registers& regs, u32 instr) {
|
||||
regs.gpr[RD(instr)] = (u64)regs.gpr[RS(instr)] < (u64)regs.gpr[RT(instr)];
|
||||
if(likely(RD(instr) != 0)) {
|
||||
regs.gpr[RD(instr)] = (u64) regs.gpr[RS(instr)] < (u64) regs.gpr[RT(instr)];
|
||||
}
|
||||
}
|
||||
|
||||
void xori(Registers& regs, u32 instr) {
|
||||
@@ -591,7 +609,9 @@ void xori(Registers& regs, u32 instr) {
|
||||
}
|
||||
|
||||
void xor_(Registers& regs, u32 instr) {
|
||||
regs.gpr[RD(instr)] = regs.gpr[RT(instr)] ^ regs.gpr[RS(instr)];
|
||||
if(likely(RD(instr) != 0)) {
|
||||
regs.gpr[RD(instr)] = regs.gpr[RT(instr)] ^ regs.gpr[RS(instr)];
|
||||
}
|
||||
}
|
||||
|
||||
void andi(Registers& regs, u32 instr) {
|
||||
@@ -600,110 +620,142 @@ void andi(Registers& regs, u32 instr) {
|
||||
}
|
||||
|
||||
void and_(Registers& regs, u32 instr) {
|
||||
regs.gpr[RD(instr)] = regs.gpr[RS(instr)] & regs.gpr[RT(instr)];
|
||||
if(likely(RD(instr) != 0)) {
|
||||
regs.gpr[RD(instr)] = regs.gpr[RS(instr)] & regs.gpr[RT(instr)];
|
||||
}
|
||||
}
|
||||
|
||||
void sll(Registers& regs, u32 instr) {
|
||||
u8 sa = ((instr >> 6) & 0x1f);
|
||||
s32 result = regs.gpr[RT(instr)] << sa;
|
||||
regs.gpr[RD(instr)] = (s64)result;
|
||||
if(likely(RD(instr) != 0)) {
|
||||
u8 sa = ((instr >> 6) & 0x1f);
|
||||
s32 result = regs.gpr[RT(instr)] << sa;
|
||||
regs.gpr[RD(instr)] = (s64) result;
|
||||
}
|
||||
}
|
||||
|
||||
void sllv(Registers& regs, u32 instr) {
|
||||
u8 sa = (regs.gpr[RS(instr)]) & 0x1F;
|
||||
u32 rt = regs.gpr[RT(instr)];
|
||||
s32 result = rt << sa;
|
||||
regs.gpr[RD(instr)] = (s64)result;
|
||||
if(likely(RD(instr) != 0)) {
|
||||
u8 sa = (regs.gpr[RS(instr)]) & 0x1F;
|
||||
u32 rt = regs.gpr[RT(instr)];
|
||||
s32 result = rt << sa;
|
||||
regs.gpr[RD(instr)] = (s64) result;
|
||||
}
|
||||
}
|
||||
|
||||
void dsll32(Registers& regs, u32 instr) {
|
||||
u8 sa = ((instr >> 6) & 0x1f);
|
||||
s64 result = regs.gpr[RT(instr)] << (sa + 32);
|
||||
regs.gpr[RD(instr)] = result;
|
||||
if(likely(RD(instr) != 0)) {
|
||||
u8 sa = ((instr >> 6) & 0x1f);
|
||||
s64 result = regs.gpr[RT(instr)] << (sa + 32);
|
||||
regs.gpr[RD(instr)] = result;
|
||||
}
|
||||
}
|
||||
|
||||
void dsll(Registers& regs, u32 instr) {
|
||||
u8 sa = ((instr >> 6) & 0x1f);
|
||||
s64 result = regs.gpr[RT(instr)] << sa;
|
||||
regs.gpr[RD(instr)] = result;
|
||||
if(likely(RD(instr) != 0)) {
|
||||
u8 sa = ((instr >> 6) & 0x1f);
|
||||
s64 result = regs.gpr[RT(instr)] << sa;
|
||||
regs.gpr[RD(instr)] = result;
|
||||
}
|
||||
}
|
||||
|
||||
void dsllv(Registers& regs, u32 instr) {
|
||||
s64 sa = regs.gpr[RS(instr)] & 63;
|
||||
s64 result = regs.gpr[RT(instr)] << sa;
|
||||
regs.gpr[RD(instr)] = result;
|
||||
if(likely(RD(instr) != 0)) {
|
||||
s64 sa = regs.gpr[RS(instr)] & 63;
|
||||
s64 result = regs.gpr[RT(instr)] << sa;
|
||||
regs.gpr[RD(instr)] = result;
|
||||
}
|
||||
}
|
||||
|
||||
void srl(Registers& regs, u32 instr) {
|
||||
u32 rt = regs.gpr[RT(instr)];
|
||||
u8 sa = ((instr >> 6) & 0x1f);
|
||||
u32 result = rt >> sa;
|
||||
regs.gpr[RD(instr)] = (s32)result;
|
||||
if(likely(RD(instr) != 0)) {
|
||||
u32 rt = regs.gpr[RT(instr)];
|
||||
u8 sa = ((instr >> 6) & 0x1f);
|
||||
u32 result = rt >> sa;
|
||||
regs.gpr[RD(instr)] = (s32) result;
|
||||
}
|
||||
}
|
||||
|
||||
void srlv(Registers& regs, u32 instr) {
|
||||
u8 sa = (regs.gpr[RS(instr)] & 0x1F);
|
||||
u32 rt = regs.gpr[RT(instr)];
|
||||
s32 result = rt >> sa;
|
||||
regs.gpr[RD(instr)] = (s64)result;
|
||||
if(likely(RD(instr) != 0)) {
|
||||
u8 sa = (regs.gpr[RS(instr)] & 0x1F);
|
||||
u32 rt = regs.gpr[RT(instr)];
|
||||
s32 result = rt >> sa;
|
||||
regs.gpr[RD(instr)] = (s64) result;
|
||||
}
|
||||
}
|
||||
|
||||
void dsrl(Registers& regs, u32 instr) {
|
||||
u64 rt = regs.gpr[RT(instr)];
|
||||
u8 sa = ((instr >> 6) & 0x1f);
|
||||
u64 result = rt >> sa;
|
||||
regs.gpr[RD(instr)] = s64(result);
|
||||
if(likely(RD(instr) != 0)) {
|
||||
u64 rt = regs.gpr[RT(instr)];
|
||||
u8 sa = ((instr >> 6) & 0x1f);
|
||||
u64 result = rt >> sa;
|
||||
regs.gpr[RD(instr)] = s64(result);
|
||||
}
|
||||
}
|
||||
|
||||
void dsrlv(Registers& regs, u32 instr) {
|
||||
u8 amount = (regs.gpr[RS(instr)] & 63);
|
||||
u64 rt = regs.gpr[RT(instr)];
|
||||
u64 result = rt >> amount;
|
||||
regs.gpr[RD(instr)] = s64(result);
|
||||
if(likely(RD(instr) != 0)) {
|
||||
u8 amount = (regs.gpr[RS(instr)] & 63);
|
||||
u64 rt = regs.gpr[RT(instr)];
|
||||
u64 result = rt >> amount;
|
||||
regs.gpr[RD(instr)] = s64(result);
|
||||
}
|
||||
}
|
||||
|
||||
void dsrl32(Registers& regs, u32 instr) {
|
||||
u64 rt = regs.gpr[RT(instr)];
|
||||
u8 sa = ((instr >> 6) & 0x1f);
|
||||
u64 result = rt >> (sa + 32);
|
||||
regs.gpr[RD(instr)] = s64(result);
|
||||
if(likely(RD(instr) != 0)) {
|
||||
u64 rt = regs.gpr[RT(instr)];
|
||||
u8 sa = ((instr >> 6) & 0x1f);
|
||||
u64 result = rt >> (sa + 32);
|
||||
regs.gpr[RD(instr)] = s64(result);
|
||||
}
|
||||
}
|
||||
|
||||
void sra(Registers& regs, u32 instr) {
|
||||
s64 rt = regs.gpr[RT(instr)];
|
||||
u8 sa = ((instr >> 6) & 0x1f);
|
||||
s32 result = rt >> sa;
|
||||
regs.gpr[RD(instr)] = result;
|
||||
if(likely(RD(instr) != 0)) {
|
||||
s64 rt = regs.gpr[RT(instr)];
|
||||
u8 sa = ((instr >> 6) & 0x1f);
|
||||
s32 result = rt >> sa;
|
||||
regs.gpr[RD(instr)] = result;
|
||||
}
|
||||
}
|
||||
|
||||
void srav(Registers& regs, u32 instr) {
|
||||
s64 rt = regs.gpr[RT(instr)];
|
||||
s64 rs = regs.gpr[RS(instr)];
|
||||
u8 sa = rs & 0x1f;
|
||||
s32 result = rt >> sa;
|
||||
regs.gpr[RD(instr)] = result;
|
||||
if(likely(RD(instr) != 0)) {
|
||||
s64 rt = regs.gpr[RT(instr)];
|
||||
s64 rs = regs.gpr[RS(instr)];
|
||||
u8 sa = rs & 0x1f;
|
||||
s32 result = rt >> sa;
|
||||
regs.gpr[RD(instr)] = result;
|
||||
}
|
||||
}
|
||||
|
||||
void dsra(Registers& regs, u32 instr) {
|
||||
s64 rt = regs.gpr[RT(instr)];
|
||||
u8 sa = ((instr >> 6) & 0x1f);
|
||||
s64 result = rt >> sa;
|
||||
regs.gpr[RD(instr)] = result;
|
||||
if(likely(RD(instr) != 0)) {
|
||||
s64 rt = regs.gpr[RT(instr)];
|
||||
u8 sa = ((instr >> 6) & 0x1f);
|
||||
s64 result = rt >> sa;
|
||||
regs.gpr[RD(instr)] = result;
|
||||
}
|
||||
}
|
||||
|
||||
void dsrav(Registers& regs, u32 instr) {
|
||||
s64 rt = regs.gpr[RT(instr)];
|
||||
s64 rs = regs.gpr[RS(instr)];
|
||||
s64 sa = rs & 63;
|
||||
s64 result = rt >> sa;
|
||||
regs.gpr[RD(instr)] = result;
|
||||
if(likely(RD(instr) != 0)) {
|
||||
s64 rt = regs.gpr[RT(instr)];
|
||||
s64 rs = regs.gpr[RS(instr)];
|
||||
s64 sa = rs & 63;
|
||||
s64 result = rt >> sa;
|
||||
regs.gpr[RD(instr)] = result;
|
||||
}
|
||||
}
|
||||
|
||||
void dsra32(Registers& regs, u32 instr) {
|
||||
s64 rt = regs.gpr[RT(instr)];
|
||||
u8 sa = ((instr >> 6) & 0x1f);
|
||||
s64 result = rt >> (sa + 32);
|
||||
regs.gpr[RD(instr)] = result;
|
||||
if(likely(RD(instr) != 0)) {
|
||||
s64 rt = regs.gpr[RT(instr)];
|
||||
u8 sa = ((instr >> 6) & 0x1f);
|
||||
s64 result = rt >> (sa + 32);
|
||||
regs.gpr[RD(instr)] = result;
|
||||
}
|
||||
}
|
||||
|
||||
void jr(Registers& regs, u32 instr) {
|
||||
@@ -723,15 +775,19 @@ void dsub(Registers& regs, u32 instr) {
|
||||
if(check_signed_underflow(rs, rt, result)) {
|
||||
FireException(regs, ExceptionCode::Overflow, 0, true);
|
||||
} else {
|
||||
regs.gpr[RD(instr)] = result;
|
||||
if(likely(RD(instr) != 0)) {
|
||||
regs.gpr[RD(instr)] = result;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void dsubu(Registers& regs, u32 instr) {
|
||||
u64 rt = regs.gpr[RT(instr)];
|
||||
u64 rs = regs.gpr[RS(instr)];
|
||||
u64 result = rs - rt;
|
||||
regs.gpr[RD(instr)] = s64(result);
|
||||
if(likely(RD(instr) != 0)) {
|
||||
u64 rt = regs.gpr[RT(instr)];
|
||||
u64 rs = regs.gpr[RS(instr)];
|
||||
u64 result = rs - rt;
|
||||
regs.gpr[RD(instr)] = s64(result);
|
||||
}
|
||||
}
|
||||
|
||||
void sub(Registers& regs, u32 instr) {
|
||||
@@ -741,15 +797,19 @@ void sub(Registers& regs, u32 instr) {
|
||||
if(check_signed_underflow(rs, rt, result)) {
|
||||
FireException(regs, ExceptionCode::Overflow, 0, true);
|
||||
} else {
|
||||
regs.gpr[RD(instr)] = result;
|
||||
if(likely(RD(instr) != 0)) {
|
||||
regs.gpr[RD(instr)] = result;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void subu(Registers& regs, u32 instr) {
|
||||
u32 rt = regs.gpr[RT(instr)];
|
||||
u32 rs = regs.gpr[RS(instr)];
|
||||
u32 result = rs - rt;
|
||||
regs.gpr[RD(instr)] = (s64)((s32)result);
|
||||
if(likely(RD(instr) != 0)) {
|
||||
u32 rt = regs.gpr[RT(instr)];
|
||||
u32 rs = regs.gpr[RS(instr)];
|
||||
u32 result = rs - rt;
|
||||
regs.gpr[RD(instr)] = (s64) ((s32) result);
|
||||
}
|
||||
}
|
||||
|
||||
void dmultu(Registers& regs, u32 instr) {
|
||||
@@ -785,11 +845,15 @@ void mult(Registers& regs, u32 instr) {
|
||||
}
|
||||
|
||||
void mflo(Registers& regs, u32 instr) {
|
||||
regs.gpr[RD(instr)] = regs.lo;
|
||||
if(likely(RD(instr) != 0)) {
|
||||
regs.gpr[RD(instr)] = regs.lo;
|
||||
}
|
||||
}
|
||||
|
||||
void mfhi(Registers& regs, u32 instr) {
|
||||
regs.gpr[RD(instr)] = regs.hi;
|
||||
if(likely(RD(instr) != 0)) {
|
||||
regs.gpr[RD(instr)] = regs.hi;
|
||||
}
|
||||
}
|
||||
|
||||
void mtlo(Registers& regs, u32 instr) {
|
||||
|
||||
@@ -12,15 +12,19 @@ void Interpreter::add(u32 instr) {
|
||||
if(check_signed_overflow(rs, rt, result)) {
|
||||
FireException(regs, ExceptionCode::Overflow, 0, true);
|
||||
} else {
|
||||
regs.gpr[RD(instr)] = s32(result);
|
||||
if(likely(RD(instr) != 0)) {
|
||||
regs.gpr[RD(instr)] = s32(result);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void Interpreter::addu(u32 instr) {
|
||||
s32 rs = (s32)regs.gpr[RS(instr)];
|
||||
s32 rt = (s32)regs.gpr[RT(instr)];
|
||||
s32 result = rs + rt;
|
||||
regs.gpr[RD(instr)] = result;
|
||||
if(likely(RD(instr) != 0)) {
|
||||
s32 rs = (s32)regs.gpr[RS(instr)];
|
||||
s32 rt = (s32)regs.gpr[RT(instr)];
|
||||
s32 result = rs + rt;
|
||||
regs.gpr[RD(instr)] = result;
|
||||
}
|
||||
}
|
||||
|
||||
void Interpreter::addi(u32 instr) {
|
||||
@@ -48,14 +52,18 @@ void Interpreter::dadd(u32 instr) {
|
||||
if(check_signed_overflow(rs, rt, result)) {
|
||||
FireException(regs, ExceptionCode::Overflow, 0, true);
|
||||
} else {
|
||||
regs.gpr[RD(instr)] = result;
|
||||
if(likely(RD(instr) != 0)) {
|
||||
regs.gpr[RD(instr)] = result;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void Interpreter::daddu(u32 instr) {
|
||||
s64 rs = regs.gpr[RS(instr)];
|
||||
s64 rt = regs.gpr[RT(instr)];
|
||||
regs.gpr[RD(instr)] = rs + rt;
|
||||
if(likely(RD(instr) != 0)) {
|
||||
s64 rs = regs.gpr[RS(instr)];
|
||||
s64 rt = regs.gpr[RT(instr)];
|
||||
regs.gpr[RD(instr)] = rs + rt;
|
||||
}
|
||||
}
|
||||
|
||||
void Interpreter::daddi(u32 instr) {
|
||||
@@ -583,11 +591,15 @@ void Interpreter::ori(u32 instr) {
|
||||
}
|
||||
|
||||
void Interpreter::or_(u32 instr) {
|
||||
regs.gpr[RD(instr)] = regs.gpr[RS(instr)] | regs.gpr[RT(instr)];
|
||||
if(likely(RD(instr) != 0)) {
|
||||
regs.gpr[RD(instr)] = regs.gpr[RS(instr)] | regs.gpr[RT(instr)];
|
||||
}
|
||||
}
|
||||
|
||||
void Interpreter::nor(u32 instr) {
|
||||
regs.gpr[RD(instr)] = ~(regs.gpr[RS(instr)] | regs.gpr[RT(instr)]);
|
||||
if(likely(RD(instr) != 0)) {
|
||||
regs.gpr[RD(instr)] = ~(regs.gpr[RS(instr)] | regs.gpr[RT(instr)]);
|
||||
}
|
||||
}
|
||||
|
||||
void Interpreter::j(u32 instr) {
|
||||
@@ -604,7 +616,9 @@ void Interpreter::jal(u32 instr) {
|
||||
|
||||
void Interpreter::jalr(u32 instr) {
|
||||
branch(true, regs.gpr[RS(instr)]);
|
||||
regs.gpr[RD(instr)] = regs.pc + 4;
|
||||
if(likely(RD(instr) != 0)) {
|
||||
regs.gpr[RD(instr)] = regs.pc + 4;
|
||||
}
|
||||
}
|
||||
|
||||
void Interpreter::slti(u32 instr) {
|
||||
@@ -618,11 +632,15 @@ void Interpreter::sltiu(u32 instr) {
|
||||
}
|
||||
|
||||
void Interpreter::slt(u32 instr) {
|
||||
regs.gpr[RD(instr)] = regs.gpr[RS(instr)] < regs.gpr[RT(instr)];
|
||||
if(likely(RD(instr) != 0)) {
|
||||
regs.gpr[RD(instr)] = regs.gpr[RS(instr)] < regs.gpr[RT(instr)];
|
||||
}
|
||||
}
|
||||
|
||||
void Interpreter::sltu(u32 instr) {
|
||||
regs.gpr[RD(instr)] = (u64)regs.gpr[RS(instr)] < (u64)regs.gpr[RT(instr)];
|
||||
if(likely(RD(instr) != 0)) {
|
||||
regs.gpr[RD(instr)] = (u64) regs.gpr[RS(instr)] < (u64) regs.gpr[RT(instr)];
|
||||
}
|
||||
}
|
||||
|
||||
void Interpreter::xori(u32 instr) {
|
||||
@@ -631,7 +649,9 @@ void Interpreter::xori(u32 instr) {
|
||||
}
|
||||
|
||||
void Interpreter::xor_(u32 instr) {
|
||||
regs.gpr[RD(instr)] = regs.gpr[RT(instr)] ^ regs.gpr[RS(instr)];
|
||||
if(likely(RD(instr) != 0)) {
|
||||
regs.gpr[RD(instr)] = regs.gpr[RT(instr)] ^ regs.gpr[RS(instr)];
|
||||
}
|
||||
}
|
||||
|
||||
void Interpreter::andi(u32 instr) {
|
||||
@@ -640,110 +660,142 @@ void Interpreter::andi(u32 instr) {
|
||||
}
|
||||
|
||||
void Interpreter::and_(u32 instr) {
|
||||
regs.gpr[RD(instr)] = regs.gpr[RS(instr)] & regs.gpr[RT(instr)];
|
||||
if(likely(RD(instr) != 0)) {
|
||||
regs.gpr[RD(instr)] = regs.gpr[RS(instr)] & regs.gpr[RT(instr)];
|
||||
}
|
||||
}
|
||||
|
||||
void Interpreter::sll(u32 instr) {
|
||||
u8 sa = ((instr >> 6) & 0x1f);
|
||||
s32 result = regs.gpr[RT(instr)] << sa;
|
||||
regs.gpr[RD(instr)] = (s64)result;
|
||||
if(likely(RD(instr) != 0)) {
|
||||
u8 sa = ((instr >> 6) & 0x1f);
|
||||
s32 result = regs.gpr[RT(instr)] << sa;
|
||||
regs.gpr[RD(instr)] = (s64) result;
|
||||
}
|
||||
}
|
||||
|
||||
void Interpreter::sllv(u32 instr) {
|
||||
u8 sa = (regs.gpr[RS(instr)]) & 0x1F;
|
||||
u32 rt = regs.gpr[RT(instr)];
|
||||
s32 result = rt << sa;
|
||||
regs.gpr[RD(instr)] = (s64)result;
|
||||
if(likely(RD(instr) != 0)) {
|
||||
u8 sa = (regs.gpr[RS(instr)]) & 0x1F;
|
||||
u32 rt = regs.gpr[RT(instr)];
|
||||
s32 result = rt << sa;
|
||||
regs.gpr[RD(instr)] = (s64) result;
|
||||
}
|
||||
}
|
||||
|
||||
void Interpreter::dsll32(u32 instr) {
|
||||
u8 sa = ((instr >> 6) & 0x1f);
|
||||
s64 result = regs.gpr[RT(instr)] << (sa + 32);
|
||||
regs.gpr[RD(instr)] = result;
|
||||
if(likely(RD(instr) != 0)) {
|
||||
u8 sa = ((instr >> 6) & 0x1f);
|
||||
s64 result = regs.gpr[RT(instr)] << (sa + 32);
|
||||
regs.gpr[RD(instr)] = result;
|
||||
}
|
||||
}
|
||||
|
||||
void Interpreter::dsll(u32 instr) {
|
||||
u8 sa = ((instr >> 6) & 0x1f);
|
||||
s64 result = regs.gpr[RT(instr)] << sa;
|
||||
regs.gpr[RD(instr)] = result;
|
||||
if(likely(RD(instr) != 0)) {
|
||||
u8 sa = ((instr >> 6) & 0x1f);
|
||||
s64 result = regs.gpr[RT(instr)] << sa;
|
||||
regs.gpr[RD(instr)] = result;
|
||||
}
|
||||
}
|
||||
|
||||
void Interpreter::dsllv(u32 instr) {
|
||||
s64 sa = regs.gpr[RS(instr)] & 63;
|
||||
s64 result = regs.gpr[RT(instr)] << sa;
|
||||
regs.gpr[RD(instr)] = result;
|
||||
if(likely(RD(instr) != 0)) {
|
||||
s64 sa = regs.gpr[RS(instr)] & 63;
|
||||
s64 result = regs.gpr[RT(instr)] << sa;
|
||||
regs.gpr[RD(instr)] = result;
|
||||
}
|
||||
}
|
||||
|
||||
void Interpreter::srl(u32 instr) {
|
||||
u32 rt = regs.gpr[RT(instr)];
|
||||
u8 sa = ((instr >> 6) & 0x1f);
|
||||
u32 result = rt >> sa;
|
||||
regs.gpr[RD(instr)] = (s32)result;
|
||||
if(likely(RD(instr) != 0)) {
|
||||
u32 rt = regs.gpr[RT(instr)];
|
||||
u8 sa = ((instr >> 6) & 0x1f);
|
||||
u32 result = rt >> sa;
|
||||
regs.gpr[RD(instr)] = (s32) result;
|
||||
}
|
||||
}
|
||||
|
||||
void Interpreter::srlv(u32 instr) {
|
||||
u8 sa = (regs.gpr[RS(instr)] & 0x1F);
|
||||
u32 rt = regs.gpr[RT(instr)];
|
||||
s32 result = rt >> sa;
|
||||
regs.gpr[RD(instr)] = (s64)result;
|
||||
if(likely(RD(instr) != 0)) {
|
||||
u8 sa = (regs.gpr[RS(instr)] & 0x1F);
|
||||
u32 rt = regs.gpr[RT(instr)];
|
||||
s32 result = rt >> sa;
|
||||
regs.gpr[RD(instr)] = (s64) result;
|
||||
}
|
||||
}
|
||||
|
||||
void Interpreter::dsrl(u32 instr) {
|
||||
u64 rt = regs.gpr[RT(instr)];
|
||||
u8 sa = ((instr >> 6) & 0x1f);
|
||||
u64 result = rt >> sa;
|
||||
regs.gpr[RD(instr)] = s64(result);
|
||||
if(likely(RD(instr) != 0)) {
|
||||
u64 rt = regs.gpr[RT(instr)];
|
||||
u8 sa = ((instr >> 6) & 0x1f);
|
||||
u64 result = rt >> sa;
|
||||
regs.gpr[RD(instr)] = s64(result);
|
||||
}
|
||||
}
|
||||
|
||||
void Interpreter::dsrlv(u32 instr) {
|
||||
u8 amount = (regs.gpr[RS(instr)] & 63);
|
||||
u64 rt = regs.gpr[RT(instr)];
|
||||
u64 result = rt >> amount;
|
||||
regs.gpr[RD(instr)] = s64(result);
|
||||
if(likely(RD(instr) != 0)) {
|
||||
u8 amount = (regs.gpr[RS(instr)] & 63);
|
||||
u64 rt = regs.gpr[RT(instr)];
|
||||
u64 result = rt >> amount;
|
||||
regs.gpr[RD(instr)] = s64(result);
|
||||
}
|
||||
}
|
||||
|
||||
void Interpreter::dsrl32(u32 instr) {
|
||||
u64 rt = regs.gpr[RT(instr)];
|
||||
u8 sa = ((instr >> 6) & 0x1f);
|
||||
u64 result = rt >> (sa + 32);
|
||||
regs.gpr[RD(instr)] = s64(result);
|
||||
if(likely(RD(instr) != 0)) {
|
||||
u64 rt = regs.gpr[RT(instr)];
|
||||
u8 sa = ((instr >> 6) & 0x1f);
|
||||
u64 result = rt >> (sa + 32);
|
||||
regs.gpr[RD(instr)] = s64(result);
|
||||
}
|
||||
}
|
||||
|
||||
void Interpreter::sra(u32 instr) {
|
||||
s64 rt = regs.gpr[RT(instr)];
|
||||
u8 sa = ((instr >> 6) & 0x1f);
|
||||
s32 result = rt >> sa;
|
||||
regs.gpr[RD(instr)] = result;
|
||||
if(likely(RD(instr) != 0)) {
|
||||
s64 rt = regs.gpr[RT(instr)];
|
||||
u8 sa = ((instr >> 6) & 0x1f);
|
||||
s32 result = rt >> sa;
|
||||
regs.gpr[RD(instr)] = result;
|
||||
}
|
||||
}
|
||||
|
||||
void Interpreter::srav(u32 instr) {
|
||||
s64 rt = regs.gpr[RT(instr)];
|
||||
s64 rs = regs.gpr[RS(instr)];
|
||||
u8 sa = rs & 0x1f;
|
||||
s32 result = rt >> sa;
|
||||
regs.gpr[RD(instr)] = result;
|
||||
if(likely(RD(instr) != 0)) {
|
||||
s64 rs = regs.gpr[RS(instr)];
|
||||
u8 sa = rs & 0x1f;
|
||||
s32 result = rt >> sa;
|
||||
regs.gpr[RD(instr)] = result;
|
||||
}
|
||||
}
|
||||
|
||||
void Interpreter::dsra(u32 instr) {
|
||||
s64 rt = regs.gpr[RT(instr)];
|
||||
u8 sa = ((instr >> 6) & 0x1f);
|
||||
s64 result = rt >> sa;
|
||||
regs.gpr[RD(instr)] = result;
|
||||
if(likely(RD(instr) != 0)) {
|
||||
s64 rt = regs.gpr[RT(instr)];
|
||||
u8 sa = ((instr >> 6) & 0x1f);
|
||||
s64 result = rt >> sa;
|
||||
regs.gpr[RD(instr)] = result;
|
||||
}
|
||||
}
|
||||
|
||||
void Interpreter::dsrav(u32 instr) {
|
||||
s64 rt = regs.gpr[RT(instr)];
|
||||
s64 rs = regs.gpr[RS(instr)];
|
||||
s64 sa = rs & 63;
|
||||
s64 result = rt >> sa;
|
||||
regs.gpr[RD(instr)] = result;
|
||||
if(likely(RD(instr) != 0)) {
|
||||
s64 rt = regs.gpr[RT(instr)];
|
||||
s64 rs = regs.gpr[RS(instr)];
|
||||
s64 sa = rs & 63;
|
||||
s64 result = rt >> sa;
|
||||
regs.gpr[RD(instr)] = result;
|
||||
}
|
||||
}
|
||||
|
||||
void Interpreter::dsra32(u32 instr) {
|
||||
s64 rt = regs.gpr[RT(instr)];
|
||||
u8 sa = ((instr >> 6) & 0x1f);
|
||||
s64 result = rt >> (sa + 32);
|
||||
regs.gpr[RD(instr)] = result;
|
||||
if(likely(RD(instr) != 0)) {
|
||||
s64 rt = regs.gpr[RT(instr)];
|
||||
u8 sa = ((instr >> 6) & 0x1f);
|
||||
s64 result = rt >> (sa + 32);
|
||||
regs.gpr[RD(instr)] = result;
|
||||
}
|
||||
}
|
||||
|
||||
void Interpreter::jr(u32 instr) {
|
||||
@@ -758,15 +810,19 @@ void Interpreter::dsub(u32 instr) {
|
||||
if(check_signed_underflow(rs, rt, result)) {
|
||||
FireException(regs, ExceptionCode::Overflow, 0, true);
|
||||
} else {
|
||||
regs.gpr[RD(instr)] = result;
|
||||
if(likely(RD(instr) != 0)) {
|
||||
regs.gpr[RD(instr)] = result;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void Interpreter::dsubu(u32 instr) {
|
||||
u64 rt = regs.gpr[RT(instr)];
|
||||
u64 rs = regs.gpr[RS(instr)];
|
||||
u64 result = rs - rt;
|
||||
regs.gpr[RD(instr)] = s64(result);
|
||||
if(likely(RD(instr) != 0)) {
|
||||
u64 rt = regs.gpr[RT(instr)];
|
||||
u64 rs = regs.gpr[RS(instr)];
|
||||
u64 result = rs - rt;
|
||||
regs.gpr[RD(instr)] = s64(result);
|
||||
}
|
||||
}
|
||||
|
||||
void Interpreter::sub(u32 instr) {
|
||||
@@ -776,15 +832,19 @@ void Interpreter::sub(u32 instr) {
|
||||
if(check_signed_underflow(rs, rt, result)) {
|
||||
FireException(regs, ExceptionCode::Overflow, 0, true);
|
||||
} else {
|
||||
regs.gpr[RD(instr)] = result;
|
||||
if(likely(RD(instr) != 0)) {
|
||||
regs.gpr[RD(instr)] = result;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void Interpreter::subu(u32 instr) {
|
||||
u32 rt = regs.gpr[RT(instr)];
|
||||
u32 rs = regs.gpr[RS(instr)];
|
||||
u32 result = rs - rt;
|
||||
regs.gpr[RD(instr)] = (s64)((s32)result);
|
||||
if(likely(RD(instr) != 0)) {
|
||||
u32 rt = regs.gpr[RT(instr)];
|
||||
u32 rs = regs.gpr[RS(instr)];
|
||||
u32 result = rs - rt;
|
||||
regs.gpr[RD(instr)] = (s64) ((s32) result);
|
||||
}
|
||||
}
|
||||
|
||||
void Interpreter::dmultu(u32 instr) {
|
||||
@@ -820,11 +880,15 @@ void Interpreter::mult(u32 instr) {
|
||||
}
|
||||
|
||||
void Interpreter::mflo(u32 instr) {
|
||||
regs.gpr[RD(instr)] = regs.lo;
|
||||
if(likely(RD(instr) != 0)) {
|
||||
regs.gpr[RD(instr)] = regs.lo;
|
||||
}
|
||||
}
|
||||
|
||||
void Interpreter::mfhi(u32 instr) {
|
||||
regs.gpr[RD(instr)] = regs.hi;
|
||||
if(likely(RD(instr) != 0)) {
|
||||
regs.gpr[RD(instr)] = regs.hi;
|
||||
}
|
||||
}
|
||||
|
||||
void Interpreter::mtlo(u32 instr) {
|
||||
|
||||
@@ -82,7 +82,7 @@ void AI::Step(Mem& mem, Registers& regs, int cpuCycles, float volumeL, float vol
|
||||
|
||||
if(dmaLen[0] && dmaEnable) {u32 addrHi = ((dmaAddr[0] >> 13) + dmaAddrCarry) & 0x7FF;
|
||||
dmaAddr[0] = (addrHi << 13) | (dmaAddr[0] & 0x1FFF);
|
||||
u32 data = Util::ReadAccess<u32>(mem.mmio.rdp.rdram.data(), dmaAddr[0] & RDRAM_DSIZE);
|
||||
u32 data = Util::ReadAccess<u32>(mem.mmio.rdp.rdram, dmaAddr[0] & RDRAM_DSIZE);
|
||||
s16 l = s16(data >> 16);
|
||||
s16 r = s16(data);
|
||||
|
||||
|
||||
@@ -69,7 +69,7 @@ u64 Cop0::GetReg64(u8 addr) {
|
||||
case 23: case 24: case 25:
|
||||
case 31: return openbus;
|
||||
default:
|
||||
Util::panic("Unsupported word read from COP0 register {}\n", index);
|
||||
Util::panic("Unsupported dword read from COP0 register {}\n", index);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -131,7 +131,7 @@ void Cop0::SetReg32(u8 addr, u32 value) {
|
||||
case 23: case 24: case 25:
|
||||
case 31: break;
|
||||
default:
|
||||
Util::panic("Unsupported word read from COP0 register {}\n", index);
|
||||
Util::panic("Unsupported word write from COP0 register {}\n", index);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -159,7 +159,7 @@ void Cop0::SetReg64(u8 addr, u64 value) {
|
||||
case COP0_REG_LLADDR: LLAddr = value; break;
|
||||
case COP0_REG_ERROREPC: ErrorEPC = (s64)value; break;
|
||||
default:
|
||||
Util::panic("Unsupported word write to COP0 register {}\n", addr);
|
||||
Util::panic("Unsupported dword write to COP0 register {}\n", addr);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -268,6 +268,10 @@ private:
|
||||
struct Registers;
|
||||
enum class ExceptionCode : u8;
|
||||
|
||||
enum TLBAccessType {
|
||||
LOAD, STORE
|
||||
};
|
||||
|
||||
TLBEntry* TLBTryMatch(Registers& regs, u64 vaddr, int* match);
|
||||
bool ProbeTLB(Registers& regs, TLBAccessType access_type, u64 vaddr, u32& paddr, int* match);
|
||||
void HandleTLBException(Registers& regs, u64 vaddr);
|
||||
|
||||
@@ -80,6 +80,7 @@ inline void SetCop0Reg(Registers& regs, Mem& mem, u8 index, u32 val) {
|
||||
}
|
||||
}
|
||||
|
||||
ARCH_TARGET("sse3", "avx2", "default")
|
||||
inline VPR Broadcast(const VPR& vt, int l0, int l1, int l2, int l3, int l4, int l5, int l6, int l7) {
|
||||
VPR vte{};
|
||||
vte.element[ELEMENT_INDEX(0)] = vt.element[ELEMENT_INDEX(l0)];
|
||||
@@ -93,6 +94,7 @@ inline VPR Broadcast(const VPR& vt, int l0, int l1, int l2, int l3, int l4, int
|
||||
return vte;
|
||||
}
|
||||
|
||||
ARCH_TARGET("sse3", "avx2", "default")
|
||||
inline VPR GetVTE(const VPR& vt, u8 e) {
|
||||
VPR vte{};
|
||||
e &= 0xf;
|
||||
@@ -692,6 +694,7 @@ inline u16 unsignedClamp(s64 val) {
|
||||
return val;
|
||||
}
|
||||
|
||||
ARCH_TARGET("sse4.2", "avx2", "default")
|
||||
void RSP::vabs(u32 instr) {
|
||||
VPR& vs = vpr[VS(instr)];
|
||||
VPR& vd = vpr[VD(instr)];
|
||||
@@ -716,6 +719,7 @@ void RSP::vabs(u32 instr) {
|
||||
}
|
||||
}
|
||||
|
||||
ARCH_TARGET("sse4.2", "avx2", "default")
|
||||
void RSP::vadd(u32 instr) {
|
||||
VPR& vs = vpr[VS(instr)];
|
||||
VPR& vd = vpr[VD(instr)];
|
||||
@@ -730,6 +734,7 @@ void RSP::vadd(u32 instr) {
|
||||
}
|
||||
}
|
||||
|
||||
ARCH_TARGET("sse4.2", "avx2", "default")
|
||||
void RSP::vaddc(u32 instr) {
|
||||
VPR& vs = vpr[VS(instr)];
|
||||
VPR& vd = vpr[VD(instr)];
|
||||
@@ -744,6 +749,7 @@ void RSP::vaddc(u32 instr) {
|
||||
}
|
||||
}
|
||||
|
||||
ARCH_TARGET("sse4.2", "avx2", "default")
|
||||
void RSP::vch(u32 instr) {
|
||||
int e = E2(instr);
|
||||
VPR& vs = vpr[VS(instr)];
|
||||
@@ -776,6 +782,7 @@ void RSP::vch(u32 instr) {
|
||||
}
|
||||
}
|
||||
|
||||
ARCH_TARGET("sse4.2", "avx2", "default")
|
||||
void RSP::vcr(u32 instr) {
|
||||
int e = E2(instr);
|
||||
VPR& vs = vpr[VS(instr)];
|
||||
@@ -808,6 +815,7 @@ void RSP::vcr(u32 instr) {
|
||||
}
|
||||
}
|
||||
|
||||
ARCH_TARGET("sse4.2", "avx2", "default")
|
||||
void RSP::vcl(u32 instr) {
|
||||
int e = E2(instr);
|
||||
VPR& vs = vpr[VS(instr)];
|
||||
@@ -843,6 +851,7 @@ void RSP::vcl(u32 instr) {
|
||||
}
|
||||
}
|
||||
|
||||
ARCH_TARGET("sse4.2", "avx2", "default")
|
||||
void RSP::vmov(u32 instr) {
|
||||
u8 e = E2(instr), vs = VS(instr) & 7;
|
||||
VPR& vd = vpr[VD(instr)];
|
||||
@@ -885,6 +894,7 @@ inline bool IsSignExtension(s16 hi, s16 lo) {
|
||||
return false;
|
||||
}
|
||||
|
||||
ARCH_TARGET("sse4.2", "avx2", "default")
|
||||
void RSP::vmulf(u32 instr) {
|
||||
int e = E2(instr);
|
||||
VPR& vs = vpr[VS(instr)];
|
||||
@@ -906,6 +916,7 @@ void RSP::vmulf(u32 instr) {
|
||||
}
|
||||
}
|
||||
|
||||
ARCH_TARGET("sse4.2", "avx2", "default")
|
||||
void RSP::vmulq(u32 instr) {
|
||||
VPR& vs = vpr[VS(instr)];
|
||||
VPR vte = GetVTE(vpr[VT(instr)], E2(instr));
|
||||
@@ -924,6 +935,7 @@ void RSP::vmulq(u32 instr) {
|
||||
}
|
||||
}
|
||||
|
||||
ARCH_TARGET("sse4.2", "avx2", "default")
|
||||
void RSP::vmulu(u32 instr) {
|
||||
int e = E2(instr);
|
||||
VPR& vs = vpr[VS(instr)];
|
||||
@@ -945,6 +957,7 @@ void RSP::vmulu(u32 instr) {
|
||||
}
|
||||
}
|
||||
|
||||
ARCH_TARGET("sse4.2", "avx2", "default")
|
||||
void RSP::vmudl(u32 instr) {
|
||||
u8 e = E2(instr);
|
||||
VPR& vs = vpr[VS(instr)];
|
||||
@@ -971,6 +984,7 @@ void RSP::vmudl(u32 instr) {
|
||||
}
|
||||
}
|
||||
|
||||
ARCH_TARGET("sse4.2", "avx2", "default")
|
||||
void RSP::vmudh(u32 instr) {
|
||||
int e = E2(instr);
|
||||
VPR& vs = vpr[VS(instr)];
|
||||
@@ -989,6 +1003,7 @@ void RSP::vmudh(u32 instr) {
|
||||
}
|
||||
}
|
||||
|
||||
ARCH_TARGET("sse4.2", "avx2", "default")
|
||||
void RSP::vmudm(u32 instr) {
|
||||
int e = E2(instr);
|
||||
VPR& vs = vpr[VS(instr)];
|
||||
@@ -1005,6 +1020,7 @@ void RSP::vmudm(u32 instr) {
|
||||
}
|
||||
}
|
||||
|
||||
ARCH_TARGET("sse4.2", "avx2", "default")
|
||||
void RSP::vmudn(u32 instr) {
|
||||
int e = E2(instr);
|
||||
VPR& vs = vpr[VS(instr)];
|
||||
@@ -1030,6 +1046,7 @@ void RSP::vmudn(u32 instr) {
|
||||
}
|
||||
}
|
||||
|
||||
ARCH_TARGET("sse4.2", "avx2", "default")
|
||||
void RSP::vmadh(u32 instr) {
|
||||
int e = E2(instr);
|
||||
VPR& vs = vpr[VS(instr)];
|
||||
@@ -1052,6 +1069,7 @@ void RSP::vmadh(u32 instr) {
|
||||
}
|
||||
}
|
||||
|
||||
ARCH_TARGET("sse4.2", "avx2", "default")
|
||||
void RSP::vmadl(u32 instr) {
|
||||
int e = E2(instr);
|
||||
VPR& vs = vpr[VS(instr)];
|
||||
@@ -1080,6 +1098,7 @@ void RSP::vmadl(u32 instr) {
|
||||
}
|
||||
}
|
||||
|
||||
ARCH_TARGET("sse4.2", "avx2", "default")
|
||||
void RSP::vmadm(u32 instr) {
|
||||
int e = E2(instr);
|
||||
VPR& vs = vpr[VS(instr)];
|
||||
@@ -1099,6 +1118,7 @@ void RSP::vmadm(u32 instr) {
|
||||
}
|
||||
}
|
||||
|
||||
ARCH_TARGET("sse4.2", "avx2", "default")
|
||||
void RSP::vmadn(u32 instr) {
|
||||
int e = E2(instr);
|
||||
VPR& vs = vpr[VS(instr)];
|
||||
@@ -1124,6 +1144,7 @@ void RSP::vmadn(u32 instr) {
|
||||
}
|
||||
}
|
||||
|
||||
ARCH_TARGET("sse4.2", "avx2", "default")
|
||||
void RSP::vmacf(u32 instr) {
|
||||
VPR& vd = vpr[VD(instr)];
|
||||
VPR& vs = vpr[VS(instr)];
|
||||
@@ -1145,6 +1166,7 @@ void RSP::vmacf(u32 instr) {
|
||||
}
|
||||
}
|
||||
|
||||
ARCH_TARGET("sse4.2", "avx2", "default")
|
||||
void RSP::vmacu(u32 instr) {
|
||||
VPR& vd = vpr[VD(instr)];
|
||||
VPR& vs = vpr[VS(instr)];
|
||||
@@ -1165,6 +1187,7 @@ void RSP::vmacu(u32 instr) {
|
||||
}
|
||||
}
|
||||
|
||||
ARCH_TARGET("sse4.2", "avx2", "default")
|
||||
void RSP::vmacq(u32 instr) {
|
||||
VPR& vd = vpr[VD(instr)];
|
||||
|
||||
@@ -1182,6 +1205,7 @@ void RSP::vmacq(u32 instr) {
|
||||
}
|
||||
}
|
||||
|
||||
ARCH_TARGET("sse4.2", "avx2", "default")
|
||||
void RSP::veq(u32 instr) {
|
||||
int e = E2(instr);
|
||||
VPR& vd = vpr[VD(instr)];
|
||||
@@ -1196,6 +1220,7 @@ void RSP::veq(u32 instr) {
|
||||
}
|
||||
}
|
||||
|
||||
ARCH_TARGET("sse4.2", "avx2", "default")
|
||||
void RSP::vne(u32 instr) {
|
||||
int e = E2(instr);
|
||||
VPR& vd = vpr[VD(instr)];
|
||||
@@ -1210,6 +1235,7 @@ void RSP::vne(u32 instr) {
|
||||
}
|
||||
}
|
||||
|
||||
ARCH_TARGET("sse4.2", "avx2", "default")
|
||||
void RSP::vge(u32 instr) {
|
||||
int e = E2(instr);
|
||||
VPR& vd = vpr[VD(instr)];
|
||||
@@ -1226,6 +1252,7 @@ void RSP::vge(u32 instr) {
|
||||
}
|
||||
}
|
||||
|
||||
ARCH_TARGET("sse4.2", "avx2", "default")
|
||||
void RSP::vlt(u32 instr) {
|
||||
int e = E2(instr);
|
||||
VPR& vd = vpr[VD(instr)];
|
||||
@@ -1287,6 +1314,7 @@ inline u32 rsq(u32 input) {
|
||||
return result ^ mask;
|
||||
}
|
||||
|
||||
ARCH_TARGET("sse4.2", "avx2", "default")
|
||||
void RSP::vrcpl(u32 instr) {
|
||||
VPR& vd = vpr[VD(instr)];
|
||||
VPR& vt = vpr[VT(instr)];
|
||||
@@ -1313,6 +1341,7 @@ void RSP::vrcpl(u32 instr) {
|
||||
vd.element[ELEMENT_INDEX(de)] = result;
|
||||
}
|
||||
|
||||
ARCH_TARGET("sse4.2", "avx2", "default")
|
||||
void RSP::vrcp(u32 instr) {
|
||||
VPR& vd = vpr[VD(instr)];
|
||||
VPR& vt = vpr[VT(instr)];
|
||||
@@ -1330,6 +1359,7 @@ void RSP::vrcp(u32 instr) {
|
||||
}
|
||||
}
|
||||
|
||||
ARCH_TARGET("sse4.2", "avx2", "default")
|
||||
void RSP::vrsq(u32 instr) {
|
||||
VPR& vd = vpr[VD(instr)];
|
||||
VPR& vt = vpr[VT(instr)];
|
||||
@@ -1354,6 +1384,7 @@ static inline s64 sclip(s64 x, u32 bits) {
|
||||
return ((x & m) ^ b) - b;
|
||||
}
|
||||
|
||||
ARCH_TARGET("sse4.2", "avx2", "default")
|
||||
void RSP::vrndn(u32 instr) {
|
||||
VPR& vd = vpr[VD(instr)];
|
||||
VPR vte = GetVTE(vpr[VT(instr)], E2(instr));
|
||||
@@ -1385,6 +1416,7 @@ void RSP::vrndn(u32 instr) {
|
||||
}
|
||||
}
|
||||
|
||||
ARCH_TARGET("sse4.2", "avx2", "default")
|
||||
void RSP::vrndp(u32 instr) {
|
||||
VPR& vd = vpr[VD(instr)];
|
||||
VPR vte = GetVTE(vpr[VT(instr)], E2(instr));
|
||||
@@ -1416,6 +1448,7 @@ void RSP::vrndp(u32 instr) {
|
||||
}
|
||||
}
|
||||
|
||||
ARCH_TARGET("sse4.2", "avx2", "default")
|
||||
void RSP::vrsql(u32 instr) {
|
||||
VPR& vd = vpr[VD(instr)];
|
||||
VPR& vt = vpr[VT(instr)];
|
||||
@@ -1441,6 +1474,7 @@ void RSP::vrsql(u32 instr) {
|
||||
vd.element[ELEMENT_INDEX(de)] = result;
|
||||
}
|
||||
|
||||
ARCH_TARGET("sse4.2", "avx2", "default")
|
||||
void RSP::vrcph(u32 instr) {
|
||||
int e = E2(instr) & 7;
|
||||
int de = DE(instr) & 7;
|
||||
@@ -1457,6 +1491,7 @@ void RSP::vrcph(u32 instr) {
|
||||
divInLoaded = true;
|
||||
}
|
||||
|
||||
ARCH_TARGET("sse4.2", "avx2", "default")
|
||||
void RSP::vsar(u32 instr) {
|
||||
u8 e = E2(instr);
|
||||
switch(e) {
|
||||
@@ -1483,6 +1518,7 @@ void RSP::vsar(u32 instr) {
|
||||
}
|
||||
}
|
||||
|
||||
ARCH_TARGET("sse4.2", "avx2", "default")
|
||||
void RSP::vsubc(u32 instr) {
|
||||
int e = E2(instr);
|
||||
VPR& vs = vpr[VS(instr)];
|
||||
@@ -1499,6 +1535,7 @@ void RSP::vsubc(u32 instr) {
|
||||
}
|
||||
}
|
||||
|
||||
ARCH_TARGET("sse4.2", "avx2", "default")
|
||||
void RSP::vsub(u32 instr) {
|
||||
int e = E2(instr);
|
||||
VPR& vs = vpr[VS(instr)];
|
||||
@@ -1515,6 +1552,7 @@ void RSP::vsub(u32 instr) {
|
||||
}
|
||||
}
|
||||
|
||||
ARCH_TARGET("sse4.2", "avx2", "default")
|
||||
void RSP::vmrg(u32 instr) {
|
||||
int e = E2(instr);
|
||||
VPR& vs = vpr[VS(instr)];
|
||||
@@ -1529,6 +1567,7 @@ void RSP::vmrg(u32 instr) {
|
||||
}
|
||||
}
|
||||
|
||||
ARCH_TARGET("sse4.2", "avx2", "default")
|
||||
void RSP::vxor(u32 instr) {
|
||||
int e = E2(instr);
|
||||
VPR& vs = vpr[VS(instr)];
|
||||
@@ -1541,6 +1580,7 @@ void RSP::vxor(u32 instr) {
|
||||
}
|
||||
}
|
||||
|
||||
ARCH_TARGET("sse4.2", "avx2", "default")
|
||||
void RSP::vnxor(u32 instr) {
|
||||
int e = E2(instr);
|
||||
VPR& vs = vpr[VS(instr)];
|
||||
@@ -1553,6 +1593,7 @@ void RSP::vnxor(u32 instr) {
|
||||
}
|
||||
}
|
||||
|
||||
ARCH_TARGET("sse4.2", "avx2", "default")
|
||||
void RSP::vand(u32 instr) {
|
||||
int e = E2(instr);
|
||||
VPR& vs = vpr[VS(instr)];
|
||||
@@ -1565,6 +1606,7 @@ void RSP::vand(u32 instr) {
|
||||
}
|
||||
}
|
||||
|
||||
ARCH_TARGET("sse4.2", "avx2", "default")
|
||||
void RSP::vnand(u32 instr) {
|
||||
int e = E2(instr);
|
||||
VPR& vs = vpr[VS(instr)];
|
||||
@@ -1577,6 +1619,7 @@ void RSP::vnand(u32 instr) {
|
||||
}
|
||||
}
|
||||
|
||||
ARCH_TARGET("sse4.2", "avx2", "default")
|
||||
void RSP::vnor(u32 instr) {
|
||||
int e = E2(instr);
|
||||
VPR& vs = vpr[VS(instr)];
|
||||
@@ -1589,6 +1632,7 @@ void RSP::vnor(u32 instr) {
|
||||
}
|
||||
}
|
||||
|
||||
ARCH_TARGET("sse4.2", "avx2", "default")
|
||||
void RSP::vor(u32 instr) {
|
||||
int e = E2(instr);
|
||||
VPR& vs = vpr[VS(instr)];
|
||||
@@ -1601,6 +1645,7 @@ void RSP::vor(u32 instr) {
|
||||
}
|
||||
}
|
||||
|
||||
ARCH_TARGET("sse4.2", "avx2", "default")
|
||||
void RSP::vzero(u32 instr) {
|
||||
VPR& vs = vpr[VS(instr)];
|
||||
VPR vte = GetVTE(vpr[VT(instr)], E2(instr));
|
||||
|
||||
Reference in New Issue
Block a user