CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutSign UpSign In
hrydgard

CoCalc provides the best real-time collaborative environment for Jupyter Notebooks, LaTeX documents, and SageMath, scalable from individual users to large groups and classes!

GitHub Repository: hrydgard/ppsspp
Path: blob/master/android/jni/ArmEmitterTest.cpp
Views: 1401
1
#include "ArmEmitterTest.h"
2
3
#include "Common/ArmEmitter.h"
4
#include "Common/CPUDetect.h"
5
6
static bool functionWasCalled;
7
8
using namespace ArmGen;
9
10
class TestCode : public ArmGen::ARMXCodeBlock {
11
public:
12
TestCode();
13
void Generate();
14
const u8 *testCodePtr;
15
const u8 *testCodePtr2;
16
};
17
18
TestCode::TestCode()
19
{
20
AllocCodeSpace(0x10000);
21
}
22
23
static float abc[256] = {1.0f, 2.0f, 0.0f};
24
25
static float a[4] = {1.0f, 2.0f, 3.0f, 4.5f};
26
static float b[4] = {1.0f, 1.0f, 1.0f, 0.5f};
27
static float c[4] = {0.0f, 0.0f, 0.0f, 0.0f};
28
29
static u32 x[4] = {0x04030201, 0x08070605, 0x0, 0x0};
30
static u32 y[4] = {0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF};
31
static u32 z[4] = {0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF};
32
33
void TestCode::Generate()
34
{
35
testCodePtr = this->GetCodePtr();
36
// Sonic1 commented that R11 is the frame pointer in debug mode, whatever "debug mode" means.
37
PUSH(2, R11, R_LR);
38
39
// Load the three pointers
40
/*
41
MOVP2R(R0, a);
42
MOVP2R(R1, b);
43
MOVP2R(R2, c);
44
45
// Load from two, do the operation, write to the third.
46
VLD1(F_32, D0, R0, 2); // Load 2 doubles
47
VLD1(F_32, D2, R1, 2); // Load another 2 doubles
48
// VADD(F_32, Q2, Q0, Q1); // Add them, seeing them as floating point quads
49
VMUL_scalar(F_32, Q2, Q0, DScalar(D3, 1)); // Multiply a quad by a scalar (ultra efficient for matrix mul! limitation: Scalar has to come out of D0-D15)
50
ADD(R1, R1, 12);
51
VLD1_all_lanes(F_32, Q2, R1, true);
52
ADD(R0, R0, 12);
53
VLD1_lane(F_32, D4, R0, 1, true);
54
// VMUL(F_32, Q2, Q0, Q1);
55
VST1(F_32, D4, R2, 2);
56
*/
57
58
// Let's try some integer stuff
59
MOVP2R(R0, x);
60
MOVP2R(R1, y);
61
MOVP2R(R2, z);
62
MOVP2R(R3, c);
63
VLD1(I_32, D0, R0, 1); // Load 1 double
64
VMOVL(I_8 | I_UNSIGNED, Q1, D0);
65
VMOVL(I_16 | I_UNSIGNED, Q2, D2);
66
VCVT(F_32 | I_SIGNED, Q3, Q2);
67
VST1(I_32, D2, R1, 2);
68
VST1(I_32, D4, R2, 2);
69
VST1(I_32, D6, R3, 2);
70
PLD(R1, 32);
71
u32 word = *(u32 *)(GetCodePtr() - 4);
72
INFO_LOG(Log::System, "Instruction Word: %08x", word);
73
74
75
// This works!
76
77
// c will later be logged.
78
79
/*
80
MOVP2R(R11, &abc[0]);
81
MOVI2R(R1, 0x3f800000);
82
STR(R11, R1, 4 * (32 + 31));
83
VLDR(S0, R11, 0);
84
VLDR(S1, R11, 4);
85
VADD(S12, S0, S1);
86
VSTR(S0, R11, 4 * (32 + 31));
87
VSTR(S12, R11, 4 * (32 + 31));
88
*/
89
//VSTR(S2, R0, 8);
90
POP(2, R11, R_PC); // Yup, this is how you return.
91
92
FlushLitPool();
93
FlushIcache();
94
95
//VLDR(S1, R0, 4);
96
//VADD(S2, S0, S1);
97
//VSTR(S2, R0, 8);
98
//QuickCallFunction(R3, (void*)&TestLeaf);
99
100
//ARMABI_CallFunctionCCC((void*)&TestLeaf, 0x1, 0x100, 0x1337);
101
//ARMABI_CallFunctionCCC((void*)&TestLeaf, 0x2, 0x100, 0x31337);
102
//ARMABI_CallFunctionCCC((void*)&TestLeaf, 0x3, 0x100, 0x1337);
103
}
104
105
106
u32 CallPtr(const void *ptr)
107
{
108
return ((u32(*)())ptr)();
109
}
110
111
extern void DisassembleArm(const u8 *data, int size);
112
113
114
void ArmEmitterTest()
115
{
116
// Disabled for now.
117
return;
118
119
// If I commit with it enabled by accident, let's not blow up.
120
if (!cpu_info.bNEON)
121
return;
122
123
for (int i = 0; i < 6; i++) {
124
INFO_LOG(Log::System, "--------------------------");
125
}
126
INFO_LOG(Log::System, "--------------------------");
127
INFO_LOG(Log::System, "Running ARM emitter test!");
128
INFO_LOG(Log::System, "--------------------------");
129
130
TestCode gen;
131
gen.ReserveCodeSpace(0x1000);
132
const u8 *codeStart = gen.GetCodePtr();
133
gen.Generate();
134
135
u32 retval = CallPtr(gen.testCodePtr);
136
// INFO_LOG(Log::System, "ARM emitter test 1 passed if %f == 3.0! retval = %08x", abc[32 + 31], retval);
137
INFO_LOG(Log::System, "x: %08x %08x %08x %08x", x[0], x[1], x[2], x[3]);
138
INFO_LOG(Log::System, "y: %08x %08x %08x %08x", y[0], y[1], y[2], y[3]);
139
INFO_LOG(Log::System, "z: %08x %08x %08x %08x", z[0], z[1], z[2], z[3]);
140
INFO_LOG(Log::System, "c: %f %f %f %f", c[0], c[1], c[2], c[3]);
141
for (int i = 0; i < 6; i++) {
142
INFO_LOG(Log::System, "--------------------------");
143
}
144
// DisassembleArm(codeStart, gen.GetCodePtr()-codeStart);
145
}
146
147