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/Core/MIPS/MIPSAsm.cpp
Views: 1401
1
#include <cstdarg>
2
#include <cstring>
3
#include <memory>
4
#ifndef NO_ARMIPS
5
#include <string_view>
6
#endif
7
#include <vector>
8
9
#include "Common/CommonTypes.h"
10
#ifndef NO_ARMIPS
11
#include "ext/armips/Core/Assembler.h"
12
#include "ext/armips/Core/FileManager.h"
13
#endif
14
15
#include "Common/Data/Encoding/Utf8.h"
16
#include "Core/Debugger/SymbolMap.h"
17
#include "Core/MemMapHelpers.h"
18
#include "Core/MIPS/JitCommon/JitCommon.h"
19
#include "Core/MIPS/MIPSAsm.h"
20
21
namespace MIPSAsm
22
{
23
static std::string errorText;
24
25
std::string GetAssembleError()
26
{
27
return errorText;
28
}
29
30
#ifndef NO_ARMIPS
31
class PspAssemblerFile: public AssemblerFile
32
{
33
public:
34
PspAssemblerFile() {
35
address = 0;
36
}
37
38
bool open(bool onlyCheck) override{ return true; };
39
void close() override { };
40
bool isOpen() override { return true; };
41
bool write(void* data, size_t length) override {
42
if (!Memory::IsValidAddress((u32)(address+length-1)))
43
return false;
44
45
Memory::Memcpy((u32)address, data, (u32)length, "Debugger");
46
47
// In case this is a delay slot or combined instruction, clear cache above it too.
48
mipsr4k.InvalidateICache((u32)(address - 4), (int)length + 4);
49
50
address += length;
51
return true;
52
}
53
int64_t getVirtualAddress() override { return address; };
54
int64_t getPhysicalAddress() override { return getVirtualAddress(); };
55
int64_t getHeaderSize() override { return 0; }
56
bool seekVirtual(int64_t virtualAddress) override {
57
if (!Memory::IsValidAddress(virtualAddress))
58
return false;
59
address = virtualAddress;
60
return true;
61
}
62
bool seekPhysical(int64_t physicalAddress) override { return seekVirtual(physicalAddress); }
63
const fs::path &getFileName() override { return dummyFilename_; }
64
private:
65
u64 address;
66
fs::path dummyFilename_;
67
};
68
69
bool MipsAssembleOpcode(const char *line, DebugInterface *cpu, u32 address) {
70
std::vector<std::string> errors;
71
72
char str[64];
73
snprintf(str, 64, ".psp\n.org 0x%08X\n", address);
74
75
ArmipsArguments args;
76
args.mode = ArmipsMode::MEMORY;
77
args.content = str + std::string(line);
78
args.silent = true;
79
args.memoryFile.reset(new PspAssemblerFile());
80
args.errorsResult = &errors;
81
82
if (g_symbolMap) {
83
g_symbolMap->GetLabels(args.labels);
84
}
85
86
errorText.clear();
87
if (!runArmips(args))
88
{
89
for (size_t i = 0; i < errors.size(); i++)
90
{
91
errorText += errors[i];
92
if (i != errors.size() - 1)
93
errorText += "\n";
94
}
95
96
return false;
97
}
98
99
return true;
100
}
101
#else
102
bool MipsAssembleOpcode(const char *line, DebugInterface *cpu, u32 address) {
103
errorText = "Built without armips, cannot assemble";
104
return false;
105
}
106
#endif
107
108
} // namespace
109
110