1 #include "MinMaxTest.h"
2 #include "VuAssembler.h"
3
Execute(CTestVm & virtualMachine)4 void CMinMaxTest::Execute(CTestVm& virtualMachine)
5 {
6 auto resultReg1 = CVuAssembler::VF16;
7 auto resultReg2 = CVuAssembler::VF17;
8 auto resultReg3 = CVuAssembler::VF18;
9 auto resultReg4 = CVuAssembler::VF19;
10
11 virtualMachine.Reset();
12
13 auto microMem = reinterpret_cast<uint32*>(virtualMachine.m_microMem);
14
15 CVuAssembler assembler(microMem);
16
17 //Inspired by Dynasty Warriors 5
18 //Will use MINI on a vector, W contains alpha value as byte
19 //Which is a denormal if we interpret is as a float
20 //The denormal number should not be flushed to zero
21 //DW5 also requires that MAX preserve denormals
22
23 assembler.Write(
24 CVuAssembler::Upper::MINI(CVuAssembler::DEST_XYZW, resultReg1, CVuAssembler::VF1, CVuAssembler::VF2),
25 CVuAssembler::Lower::NOP());
26
27 assembler.Write(
28 CVuAssembler::Upper::MAX(CVuAssembler::DEST_XYZW, resultReg2, CVuAssembler::VF1, CVuAssembler::VF3),
29 CVuAssembler::Lower::NOP());
30
31 //Inspired by Gran Turismo 4
32 //MINI/MAX needs to work properly with PS2's minimum & maximum float values
33
34 assembler.Write(
35 CVuAssembler::Upper::MINI(CVuAssembler::DEST_XYZW, resultReg3, CVuAssembler::VF1, CVuAssembler::VF4),
36 CVuAssembler::Lower::NOP());
37
38 assembler.Write(
39 CVuAssembler::Upper::MAX(CVuAssembler::DEST_XYZW, resultReg4, CVuAssembler::VF5, CVuAssembler::VF1),
40 CVuAssembler::Lower::NOP());
41
42 assembler.Write(
43 CVuAssembler::Upper::NOP() | CVuAssembler::Upper::E_BIT,
44 CVuAssembler::Lower::NOP());
45
46 assembler.Write(
47 CVuAssembler::Upper::NOP(),
48 CVuAssembler::Lower::NOP());
49
50 virtualMachine.m_cpu.m_State.nCOP2[1].nV0 = Float::_1;
51 virtualMachine.m_cpu.m_State.nCOP2[1].nV1 = Float::_Minus8;
52 virtualMachine.m_cpu.m_State.nCOP2[1].nV2 = Float::_64;
53 virtualMachine.m_cpu.m_State.nCOP2[1].nV3 = 0x80;
54
55 virtualMachine.m_cpu.m_State.nCOP2[2].nV0 = Float::_8;
56 virtualMachine.m_cpu.m_State.nCOP2[2].nV1 = Float::_8;
57 virtualMachine.m_cpu.m_State.nCOP2[2].nV2 = Float::_8;
58 virtualMachine.m_cpu.m_State.nCOP2[2].nV3 = Float::_8;
59
60 virtualMachine.m_cpu.m_State.nCOP2[3].nV0 = Float::_Minus1;
61 virtualMachine.m_cpu.m_State.nCOP2[3].nV1 = Float::_Minus1;
62 virtualMachine.m_cpu.m_State.nCOP2[3].nV2 = Float::_Minus1;
63 virtualMachine.m_cpu.m_State.nCOP2[3].nV3 = Float::_Minus1;
64
65 virtualMachine.m_cpu.m_State.nCOP2[4].nV0 = Float::_Max;
66 virtualMachine.m_cpu.m_State.nCOP2[4].nV1 = Float::_Max;
67 virtualMachine.m_cpu.m_State.nCOP2[4].nV2 = Float::_Max;
68 virtualMachine.m_cpu.m_State.nCOP2[4].nV3 = Float::_Max;
69
70 virtualMachine.m_cpu.m_State.nCOP2[5].nV0 = Float::_Min;
71 virtualMachine.m_cpu.m_State.nCOP2[5].nV1 = Float::_Min;
72 virtualMachine.m_cpu.m_State.nCOP2[5].nV2 = Float::_Min;
73 virtualMachine.m_cpu.m_State.nCOP2[5].nV3 = Float::_Min;
74
75 virtualMachine.ExecuteTest(0);
76
77 TEST_VERIFY(virtualMachine.m_cpu.m_State.nCOP2[resultReg1].nV0 == Float::_1);
78 TEST_VERIFY(virtualMachine.m_cpu.m_State.nCOP2[resultReg1].nV1 == Float::_Minus8);
79 TEST_VERIFY(virtualMachine.m_cpu.m_State.nCOP2[resultReg1].nV2 == Float::_8);
80 TEST_VERIFY(virtualMachine.m_cpu.m_State.nCOP2[resultReg1].nV3 == 0x80);
81
82 TEST_VERIFY(virtualMachine.m_cpu.m_State.nCOP2[resultReg2].nV0 == Float::_1);
83 TEST_VERIFY(virtualMachine.m_cpu.m_State.nCOP2[resultReg2].nV1 == Float::_Minus1);
84 TEST_VERIFY(virtualMachine.m_cpu.m_State.nCOP2[resultReg2].nV2 == Float::_64);
85 TEST_VERIFY(virtualMachine.m_cpu.m_State.nCOP2[resultReg2].nV3 == 0x80);
86
87 TEST_VERIFY(virtualMachine.m_cpu.m_State.nCOP2[resultReg3].nV0 == Float::_1);
88 TEST_VERIFY(virtualMachine.m_cpu.m_State.nCOP2[resultReg3].nV1 == Float::_Minus8);
89 TEST_VERIFY(virtualMachine.m_cpu.m_State.nCOP2[resultReg3].nV2 == Float::_64);
90 TEST_VERIFY(virtualMachine.m_cpu.m_State.nCOP2[resultReg3].nV3 == 0x80);
91
92 TEST_VERIFY(virtualMachine.m_cpu.m_State.nCOP2[resultReg4].nV0 == Float::_1);
93 TEST_VERIFY(virtualMachine.m_cpu.m_State.nCOP2[resultReg4].nV1 == Float::_Minus8);
94 TEST_VERIFY(virtualMachine.m_cpu.m_State.nCOP2[resultReg4].nV2 == Float::_64);
95 TEST_VERIFY(virtualMachine.m_cpu.m_State.nCOP2[resultReg4].nV3 == 0x80);
96 }
97