Add another stall test.

This commit is contained in:
Jean-Philip Desjardins 2020-02-26 20:09:18 -05:00
parent 674bf59970
commit e268a7beb1
6 changed files with 146 additions and 0 deletions

View file

@ -22,6 +22,7 @@ add_executable(VuTest
FlagsTest3.cpp
Main.cpp
StallTest.cpp
StallTest2.cpp
TestVm.cpp
TriAceTest.cpp
VuAssembler.cpp
@ -31,6 +32,7 @@ add_executable(VuTest
FlagsTest2.h
FlagsTest3.h
StallTest.h
StallTest2.h
Test.h
TestVm.h
TriAceTest.h

View file

@ -6,6 +6,7 @@
#include "FlagsTest2.h"
#include "FlagsTest3.h"
#include "StallTest.h"
#include "StallTest2.h"
#include "TriAceTest.h"
typedef std::function<CTest*()> TestFactoryFunction;
@ -18,6 +19,7 @@ static const TestFactoryFunction s_factories[] =
[]() { return new CFlagsTest2(); },
[]() { return new CFlagsTest3(); },
[]() { return new CStallTest(); },
[]() { return new CStallTest2(); },
[]() { return new CTriAceTest(); },
};
// clang-format on

View file

@ -0,0 +1,60 @@
#include "StallTest2.h"
#include "VuAssembler.h"
void CStallTest2::Execute(CTestVm& virtualMachine)
{
virtualMachine.Reset();
auto microMem = reinterpret_cast<uint32*>(virtualMachine.m_microMem);
//Inspired by Crimson Tears - FMAC stall has an impact on clip result availability
CVuAssembler assembler(microMem);
//pipeTime = 0
//Writing to VF20xyzw here, results will be available at pipeTime 4
assembler.Write(
CVuAssembler::Upper::NOP(),
CVuAssembler::Lower::LQ(CVuAssembler::DEST_XYZW, CVuAssembler::VF20, 0xE, CVuAssembler::VI6)
);
//pipeTime = 1
//CLIP result will be available at pipeTime 5
assembler.Write(
CVuAssembler::Upper::CLIP(CVuAssembler::VF25, CVuAssembler::VF0),
CVuAssembler::Lower::IADDIU(CVuAssembler::VI6, CVuAssembler::VI6, 0x01)
);
//pipeTime = 2
assembler.Write(
CVuAssembler::Upper::FTOI4(CVuAssembler::DEST_XYZW, CVuAssembler::VF15, CVuAssembler::VF15),
CVuAssembler::Lower::LQ(CVuAssembler::DEST_Y, CVuAssembler::VF12, 0x0D, CVuAssembler::VI0)
);
//pipeTime = 3, 4
//FMAC stalling till pipeTime 4 because results in VF20xyzw are not ready
assembler.Write(
CVuAssembler::Upper::ITOF12(CVuAssembler::DEST_XYZW, CVuAssembler::VF20, CVuAssembler::VF20),
CVuAssembler::Lower::SQ(CVuAssembler::DEST_XYZW, CVuAssembler::VF24, 0x01, CVuAssembler::VI10)
);
//pipeTime = 5
assembler.Write(
CVuAssembler::Upper::NOP(),
CVuAssembler::Lower::FCAND(0x3F)
);
assembler.Write(
CVuAssembler::Upper::NOP() | CVuAssembler::Upper::E_BIT,
CVuAssembler::Lower::NOP());
assembler.Write(
CVuAssembler::Upper::NOP(),
CVuAssembler::Lower::NOP());
virtualMachine.m_cpu.m_State.nCOP2[25] = MakeVector(2.0f, 2.0f, 2.0f, 1.0f);
virtualMachine.ExecuteTest(0);
TEST_VERIFY(virtualMachine.m_cpu.m_State.nCOP2VI[1] == 1);
}

View file

@ -0,0 +1,9 @@
#pragma once
#include "Test.h"
class CStallTest2 : public CTest
{
public:
void Execute(CTestVm&) override;
};

View file

@ -1,4 +1,5 @@
#include "VuAssembler.h"
#include <cassert>
CVuAssembler::CVuAssembler(uint32* ptr)
: m_ptr(ptr)
@ -29,6 +30,23 @@ uint32 CVuAssembler::Upper::ADDi(DEST dest, VF_REGISTER fd, VF_REGISTER fs)
return result;
}
uint32 CVuAssembler::Upper::CLIP(VF_REGISTER fs, VF_REGISTER ft)
{
uint32 result = 0x01E001FF;
result |= (fs << 11);
result |= (ft << 16);
return result;
}
uint32 CVuAssembler::Upper::FTOI4(DEST dest, VF_REGISTER ft, VF_REGISTER fs)
{
uint32 result = 0x0000017D;
result |= (fs << 11);
result |= (ft << 16);
result |= (dest << 21);
return result;
}
uint32 CVuAssembler::Upper::ITOF0(DEST dest, VF_REGISTER ft, VF_REGISTER fs)
{
uint32 result = 0x0000013C;
@ -38,6 +56,15 @@ uint32 CVuAssembler::Upper::ITOF0(DEST dest, VF_REGISTER ft, VF_REGISTER fs)
return result;
}
uint32 CVuAssembler::Upper::ITOF12(DEST dest, VF_REGISTER ft, VF_REGISTER fs)
{
uint32 result = 0x0000013E;
result |= (fs << 11);
result |= (ft << 16);
result |= (dest << 21);
return result;
}
uint32 CVuAssembler::Upper::MADDbc(DEST dest, VF_REGISTER fd, VF_REGISTER fs, VF_REGISTER ft, BROADCAST bc)
{
uint32 result = 0x00000008;
@ -134,6 +161,13 @@ uint32 CVuAssembler::Lower::DIV(VF_REGISTER fs, FVF fsf, VF_REGISTER ft, FVF ftf
return result;
}
uint32 CVuAssembler::Lower::FCAND(uint32 imm)
{
uint32 result = 0x24000000;
result |= (imm & 0xFFFFFF);
return result;
}
uint32 CVuAssembler::Lower::FMAND(VI_REGISTER it, VI_REGISTER is)
{
uint32 result = 0x34000000;
@ -152,11 +186,43 @@ uint32 CVuAssembler::Lower::FSAND(VI_REGISTER it, uint16 imm)
return result;
}
uint32 CVuAssembler::Lower::IADDIU(VI_REGISTER it, VI_REGISTER is, uint16 imm)
{
assert(imm <= 0x7FFF);
imm &= 0x7FFF;
uint32 result = 0x10000000;
result |= (it << 16);
result |= (is << 11);
result |= (imm & 0x7FF);
result |= (((imm & 0x7800) >> 11) << 21);
return result;
}
uint32 CVuAssembler::Lower::LQ(DEST dest, VF_REGISTER ft, uint16 imm, VI_REGISTER is)
{
uint32 result = 0x00000000;
result |= (imm & 0x7FF);
result |= (is << 11);
result |= (ft << 16);
result |= (dest << 21);
return result;
}
uint32 CVuAssembler::Lower::NOP()
{
return 0x8000033C;
}
uint32 CVuAssembler::Lower::SQ(DEST dest, VF_REGISTER fs, uint16 imm, VI_REGISTER it)
{
uint32 result = 0x02000000;
result |= (imm & 0x7FF);
result |= (fs << 11);
result |= (it << 16);
result |= (dest << 21);
return result;
}
uint32 CVuAssembler::Lower::WAITQ()
{
return 0x800003BF;

View file

@ -112,7 +112,10 @@ public:
};
static uint32 ADDi(DEST, VF_REGISTER, VF_REGISTER);
static uint32 CLIP(VF_REGISTER, VF_REGISTER);
static uint32 FTOI4(DEST, VF_REGISTER, VF_REGISTER);
static uint32 ITOF0(DEST, VF_REGISTER, VF_REGISTER);
static uint32 ITOF12(DEST, VF_REGISTER, VF_REGISTER);
static uint32 MADDbc(DEST, VF_REGISTER, VF_REGISTER, VF_REGISTER, BROADCAST);
static uint32 MADDAbc(DEST, VF_REGISTER, VF_REGISTER, BROADCAST);
static uint32 MULi(DEST, VF_REGISTER, VF_REGISTER);
@ -128,9 +131,13 @@ public:
{
public:
static uint32 DIV(VF_REGISTER, FVF, VF_REGISTER, FVF);
static uint32 FCAND(uint32);
static uint32 FMAND(VI_REGISTER, VI_REGISTER);
static uint32 FSAND(VI_REGISTER, uint16);
static uint32 IADDIU(VI_REGISTER, VI_REGISTER, uint16);
static uint32 LQ(DEST, VF_REGISTER, uint16, VI_REGISTER);
static uint32 NOP();
static uint32 SQ(DEST, VF_REGISTER, uint16, VI_REGISTER);
static uint32 WAITQ();
};