Skip to content
Snippets Groups Projects
Commit 787df2b4 authored by Geo Ster's avatar Geo Ster
Browse files

VU0: Add basic ADD/SUB/MUL instructions

* The bios uses them to initialize the VU0 registers. For now I don't
check for overflow but I think it's going to become necessary in the
near future.
parent 71aab146
No related branches found
No related tags found
No related merge requests found
...@@ -20,7 +20,7 @@ namespace vu ...@@ -20,7 +20,7 @@ namespace vu
case 0b101100: case 0b101100:
return op_vsub(vu_instr); return op_vsub(vu_instr);
case 0b110000: case 0b110000:
return op_viadd(vu_instr);
case 0b111100 ... 0b111111: case 0b111100 ... 0b111111:
return special2(instr); return special2(instr);
default: default:
...@@ -37,6 +37,10 @@ namespace vu ...@@ -37,6 +37,10 @@ namespace vu
VUInstr vu_instr = { .value = instr.value }; VUInstr vu_instr = { .value = instr.value };
switch (opcode) switch (opcode)
{ {
case 0b0000100: op_vsuba(vu_instr); break;
case 0b0001000: op_vmadda(vu_instr); break;
case 0b0001100: op_vmsuba(vu_instr); break;
case 0b0010000: op_vitof0(vu_instr); break;
case 0b0111111: op_viswr(vu_instr); break; case 0b0111111: op_viswr(vu_instr); break;
case 0b0110101: op_vsqi(vu_instr); break; case 0b0110101: op_vsqi(vu_instr); break;
default: default:
...@@ -157,4 +161,63 @@ namespace vu ...@@ -157,4 +161,63 @@ namespace vu
fmt::print("[VU0] VIADD VI[{}] = VI[{}] ({:#x}) + VI[{}] ({:#x})\n", id, is, regs.vi[is], it, regs.vi[it]); fmt::print("[VU0] VIADD VI[{}] = VI[{}] ({:#x}) + VI[{}] ({:#x})\n", id, is, regs.vi[is], it, regs.vi[it]);
regs.vi[id] = regs.vi[is] + regs.vi[it]; regs.vi[id] = regs.vi[is] + regs.vi[it];
} }
void VU0::op_vsuba(VUInstr instr)
{
uint16_t fs = instr.fs;
uint16_t ft = instr.ft;
fmt::print("[VU0] VSUBA Writing VF[{}] - VF[{}] (", fs, ft);
for (int i = 0; i < 4; i++)
{
/* If the component is set in the dest mask */
if (instr.dest & (1 << i))
{
fmt::print("{}, ", "XYZW"[i]);
acc.fword[i] = regs.vf[fs].fword[i] - regs.vf[ft].fword[i];
}
}
fmt::print("\b\b)\n");
}
void VU0::op_vmadda(VUInstr instr)
{
uint16_t fs = instr.fs;
uint16_t ft = instr.ft;
fmt::print("[VU0] VMADDA Writing VF[{}] * VF[{}] (", fs, ft);
for (int i = 0; i < 4; i++)
{
/* If the component is set in the dest mask */
if (instr.dest & (1 << i))
{
fmt::print("{}, ", "XYZW"[i]);
acc.fword[i] += regs.vf[fs].fword[i] * regs.vf[ft].fword[i];
}
}
fmt::print("\b\b)\n");
}
void VU0::op_vmsuba(VUInstr instr)
{
uint16_t fs = instr.fs;
uint16_t ft = instr.ft;
fmt::print("[VU0] VMSUBA Writing VF[{}] - VF[{}] (", fs, ft);
for (int i = 0; i < 4; i++)
{
/* If the component is set in the dest mask */
if (instr.dest & (1 << i))
{
fmt::print("{}, ", "XYZW"[i]);
acc.fword[i] -= regs.vf[fs].fword[i] * regs.vf[ft].fword[i];
}
}
fmt::print("\b\b)\n");
}
void VU0::op_vitof0(VUInstr instr)
{
}
} }
\ No newline at end of file
...@@ -11,10 +11,13 @@ using uint128_t = unsigned __int128; ...@@ -11,10 +11,13 @@ using uint128_t = unsigned __int128;
namespace vu namespace vu
{ {
union VF union Vector
{ {
/* The unsigned part is used to preserve bit data */
uint128_t qword; uint128_t qword;
uint32_t word[4]; uint32_t word[4];
/* Float part is used for float operations */
float fword[4];
struct { float x, y, z, w; }; struct { float x, y, z, w; };
}; };
...@@ -22,7 +25,7 @@ namespace vu ...@@ -22,7 +25,7 @@ namespace vu
{ {
uint32_t vi[16]; uint32_t vi[16];
uint32_t control[16]; uint32_t control[16];
VF vf[32]; Vector vf[32];
}; };
union VUInstr union VUInstr
...@@ -47,12 +50,6 @@ namespace vu ...@@ -47,12 +50,6 @@ namespace vu
uint32_t ft : 5; uint32_t ft : 5;
uint32_t : 11; uint32_t : 11;
}; };
VUInstr operator=(uint32_t i)
{
VUInstr v = { .value = i };
return v;
}
}; };
struct VU0 struct VU0
...@@ -73,10 +70,15 @@ namespace vu ...@@ -73,10 +70,15 @@ namespace vu
void op_vsub(VUInstr instr); void op_vsub(VUInstr instr);
void op_vsqi(VUInstr instr); void op_vsqi(VUInstr instr);
void op_viadd(VUInstr instr); void op_viadd(VUInstr instr);
void op_vsuba(VUInstr instr);
void op_vmadda(VUInstr instr);
void op_vmsuba(VUInstr instr);
void op_vitof0(VUInstr instr);
private: private:
ee::EmotionEngine* cpu; ee::EmotionEngine* cpu;
Registers regs = {}; Registers regs = {};
Vector acc;
uint8_t data[4 * 1024] = {}; uint8_t data[4 * 1024] = {};
}; };
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment