Moar RSP vector instructions

This commit is contained in:
CocoSimone
2022-09-25 18:27:07 +02:00
parent 24ec6ed6dd
commit c0fa20b10f
3 changed files with 96 additions and 3 deletions

View File

@@ -205,9 +205,11 @@ void RSP::lui(u32 instr) {
gpr[RT(instr)] = imm;
}
#define OFFSET(x) ((x) & 0x7F)
void RSP::lqv(u32 instr) {
int e = E(instr);
u32 addr = gpr[BASE(instr)] + SignExt7bit(instr & 0x7F, 4);
u32 addr = gpr[BASE(instr)] + SignExt7bit(OFFSET(instr), 4);
u32 end = ((addr & ~15) + 15);
for(int i = 0; addr + i <= end && i + e < 16; i++) {
@@ -215,6 +217,17 @@ void RSP::lqv(u32 instr) {
}
}
void RSP::ldv(u32 instr) {
int e = E(instr);
u32 addr = gpr[BASE(instr)] + SignExt7bit(OFFSET(instr), 3);
u32 end = e + 8 > 16 ? 16 : e + 8;
for(int i = e; i < end; i++) {
vpr[VT(instr)].byte[BYTE_INDEX(i)] = ReadByte(addr);
addr++;
}
}
void RSP::j(u32 instr) {
u32 target = (instr & 0x3ffffff) << 2;
nextPC = target;
@@ -281,7 +294,7 @@ void RSP::sub(u32 instr) {
void RSP::sqv(u32 instr) {
int e = E(instr);
u32 addr = gpr[BASE(instr)] + SignExt7bit(instr & 0x7F, 4);
u32 addr = gpr[BASE(instr)] + SignExt7bit(OFFSET(instr), 4);
u32 end = ((addr & ~15) + 15);
for(int i = 0; addr + i <= end; i++) {
@@ -289,6 +302,26 @@ void RSP::sqv(u32 instr) {
}
}
void RSP::sdv(u32 instr) {
int e = E(instr);
u32 addr = gpr[BASE(instr)] + SignExt7bit(OFFSET(instr), 3);
for(int i = 0; i < 8; i++) {
WriteByte(addr + i, vpr[VT(instr)].byte[BYTE_INDEX((i + e) & 0xF)]);
}
}
void RSP::ssv(u32 instr) {
int e = E(instr);
u32 addr = gpr[BASE(instr)] + SignExt7bit(OFFSET(instr), 1);
u8 hi = vpr[VT(instr)].byte[BYTE_INDEX(e & 15)];
u8 lo = vpr[VT(instr)].byte[BYTE_INDEX((e + 1) & 15)];
u16 val = (u16)hi << 8 | lo;
WriteHalf(addr, val);
}
void RSP::sllv(u32 instr) {
u8 sa = (gpr[RS(instr)]) & 0x1F;
u32 rt = gpr[RT(instr)];
@@ -343,6 +376,12 @@ void RSP::sltiu(u32 instr) {
gpr[RT(instr)] = (u32)gpr[RS(instr)] < imm;
}
inline s16 clamp_signed(s64 val) {
if(val > 32767) return 32767;
if(val < -32768) return -32768;
return val;
}
void RSP::vabs(u32 instr) {
}
@@ -351,6 +390,22 @@ void RSP::vmov(u32 instr) {
}
void RSP::vmacf(u32 instr) {
VPR& vd = vpr[VD(instr)];
VPR& vs = vpr[VS(instr)];
VPR vte = GetVTE(vpr[VT(instr)], E(instr));
for(int i = 0; i < 8; i++) {
s32 prod = vs.selement[i] * vte.selement[i];
s64 accDelta = prod * 2;
s64 accum = GetACC(i) + accDelta;
SetACC(i, accum);
s16 result = clamp_signed(accum >> 16);
vd.element[i] = result;
}
}
void RSP::veq(u32 instr) {
}
@@ -363,6 +418,18 @@ void RSP::vsar(u32 instr) {
}
void RSP::vzero(u32 instr) {
VPR& vs = vpr[VS(instr)];
VPR& vd = vpr[VD(instr)];
VPR vte = GetVTE(vpr[VT(instr)], E(instr));
for(int i = 0; i < 8; i++) {
acc.l.element[i] = vte.element[i] + vs.element[i];
}
memset(&vd, 0, sizeof(VPR));
}
void RSP::mfc0(RDP& rdp, u32 instr) {
gpr[RT(instr)] = GetCop0Reg(*this, rdp, RD(instr));
}