2013-09-01 21:51:06 +10:00
|
|
|
#include <cstdarg>
|
2013-12-30 21:37:19 -08:00
|
|
|
#include <cstring>
|
2018-06-29 22:19:23 -07:00
|
|
|
#include <memory>
|
2022-12-17 10:08:46 -08:00
|
|
|
#ifndef NO_ARMIPS
|
2022-01-17 11:13:24 -08:00
|
|
|
#include <string_view>
|
2022-12-17 10:08:46 -08:00
|
|
|
#endif
|
2015-12-26 20:14:14 -08:00
|
|
|
#include <vector>
|
|
|
|
|
|
|
|
#include "Common/CommonTypes.h"
|
2022-12-17 10:08:46 -08:00
|
|
|
#ifndef NO_ARMIPS
|
2014-11-22 00:11:28 +01:00
|
|
|
#include "ext/armips/Core/Assembler.h"
|
2020-08-25 18:02:45 -07:00
|
|
|
#include "ext/armips/Core/FileManager.h"
|
2022-12-17 10:08:46 -08:00
|
|
|
#endif
|
2013-09-01 10:21:05 +02:00
|
|
|
|
2020-10-01 13:05:04 +02:00
|
|
|
#include "Common/Data/Encoding/Utf8.h"
|
2015-12-26 20:14:14 -08:00
|
|
|
#include "Core/Debugger/SymbolMap.h"
|
|
|
|
#include "Core/MemMapHelpers.h"
|
2016-05-01 10:35:37 +02:00
|
|
|
#include "Core/MIPS/JitCommon/JitCommon.h"
|
2015-12-26 20:14:14 -08:00
|
|
|
#include "Core/MIPS/MIPSAsm.h"
|
|
|
|
|
2014-11-22 00:11:28 +01:00
|
|
|
namespace MIPSAsm
|
|
|
|
{
|
2022-01-17 11:13:24 -08:00
|
|
|
static std::string errorText;
|
2013-09-01 10:21:05 +02:00
|
|
|
|
2022-01-17 11:13:24 -08:00
|
|
|
std::string GetAssembleError()
|
2013-09-01 10:21:05 +02:00
|
|
|
{
|
2014-11-22 00:11:28 +01:00
|
|
|
return errorText;
|
2013-09-01 10:21:05 +02:00
|
|
|
}
|
|
|
|
|
2022-12-17 10:08:46 -08:00
|
|
|
#ifndef NO_ARMIPS
|
2014-11-22 00:11:28 +01:00
|
|
|
class PspAssemblerFile: public AssemblerFile
|
2013-07-28 14:50:25 +02:00
|
|
|
{
|
2014-11-22 00:11:28 +01:00
|
|
|
public:
|
2016-09-18 23:11:00 +02:00
|
|
|
PspAssemblerFile() {
|
2014-11-22 00:11:28 +01:00
|
|
|
address = 0;
|
2013-07-28 14:50:25 +02:00
|
|
|
}
|
|
|
|
|
2015-10-17 02:55:10 -04:00
|
|
|
bool open(bool onlyCheck) override{ return true; };
|
|
|
|
void close() override { };
|
|
|
|
bool isOpen() override { return true; };
|
2017-03-13 23:45:25 +01:00
|
|
|
bool write(void* data, size_t length) override {
|
2014-11-22 00:11:28 +01:00
|
|
|
if (!Memory::IsValidAddress((u32)(address+length-1)))
|
|
|
|
return false;
|
2013-07-28 14:50:25 +02:00
|
|
|
|
2021-04-03 17:37:47 -07:00
|
|
|
Memory::Memcpy((u32)address, data, (u32)length, "Debugger");
|
2014-11-22 00:11:28 +01:00
|
|
|
|
|
|
|
// In case this is a delay slot or combined instruction, clear cache above it too.
|
2022-10-09 21:26:13 -07:00
|
|
|
mipsr4k.InvalidateICache((u32)(address - 4), (int)length + 4);
|
2013-07-28 14:50:25 +02:00
|
|
|
|
2014-11-22 00:11:28 +01:00
|
|
|
address += length;
|
|
|
|
return true;
|
2013-07-28 14:50:25 +02:00
|
|
|
}
|
2017-03-15 19:33:33 +01:00
|
|
|
int64_t getVirtualAddress() override { return address; };
|
|
|
|
int64_t getPhysicalAddress() override { return getVirtualAddress(); };
|
|
|
|
int64_t getHeaderSize() override { return 0; }
|
2017-03-13 23:45:25 +01:00
|
|
|
bool seekVirtual(int64_t virtualAddress) override {
|
2014-11-22 00:11:28 +01:00
|
|
|
if (!Memory::IsValidAddress(virtualAddress))
|
|
|
|
return false;
|
|
|
|
address = virtualAddress;
|
|
|
|
return true;
|
2013-07-28 14:50:25 +02:00
|
|
|
}
|
2017-03-15 19:33:33 +01:00
|
|
|
bool seekPhysical(int64_t physicalAddress) override { return seekVirtual(physicalAddress); }
|
2020-08-25 18:02:45 -07:00
|
|
|
const fs::path &getFileName() override { return dummyFilename_; }
|
2014-11-22 00:11:28 +01:00
|
|
|
private:
|
|
|
|
u64 address;
|
2020-08-25 18:02:45 -07:00
|
|
|
fs::path dummyFilename_;
|
2014-11-22 00:11:28 +01:00
|
|
|
};
|
2013-07-28 14:50:25 +02:00
|
|
|
|
2022-01-17 11:13:24 -08:00
|
|
|
bool MipsAssembleOpcode(const char *line, DebugInterface *cpu, u32 address) {
|
|
|
|
std::vector<std::string> errors;
|
2014-11-22 00:11:28 +01:00
|
|
|
|
2022-01-17 11:13:24 -08:00
|
|
|
char str[64];
|
|
|
|
snprintf(str, 64, ".psp\n.org 0x%08X\n", address);
|
2014-11-22 00:11:28 +01:00
|
|
|
|
|
|
|
ArmipsArguments args;
|
2015-01-04 13:04:30 -08:00
|
|
|
args.mode = ArmipsMode::MEMORY;
|
2022-01-17 11:13:24 -08:00
|
|
|
args.content = str + std::string(line);
|
2014-11-22 00:11:28 +01:00
|
|
|
args.silent = true;
|
2018-06-29 22:19:23 -07:00
|
|
|
args.memoryFile.reset(new PspAssemblerFile());
|
2014-11-22 00:11:28 +01:00
|
|
|
args.errorsResult = &errors;
|
2017-05-06 18:45:04 -07:00
|
|
|
|
|
|
|
if (g_symbolMap) {
|
|
|
|
g_symbolMap->GetLabels(args.labels);
|
|
|
|
}
|
2014-11-09 15:14:07 -08:00
|
|
|
|
2022-09-30 12:26:30 +03:00
|
|
|
errorText.clear();
|
2014-11-22 00:11:28 +01:00
|
|
|
if (!runArmips(args))
|
2014-11-09 15:14:07 -08:00
|
|
|
{
|
2014-11-22 00:11:28 +01:00
|
|
|
for (size_t i = 0; i < errors.size(); i++)
|
2014-11-09 15:14:07 -08:00
|
|
|
{
|
2014-11-22 00:11:28 +01:00
|
|
|
errorText += errors[i];
|
2022-01-17 11:13:24 -08:00
|
|
|
if (i != errors.size() - 1)
|
|
|
|
errorText += "\n";
|
2014-11-09 15:14:07 -08:00
|
|
|
}
|
|
|
|
|
2013-07-28 14:50:25 +02:00
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
return true;
|
|
|
|
}
|
2022-12-17 10:08:46 -08:00
|
|
|
#else
|
|
|
|
bool MipsAssembleOpcode(const char *line, DebugInterface *cpu, u32 address) {
|
|
|
|
errorText = "Built without armips, cannot assemble";
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
#endif
|
2013-07-28 14:50:25 +02:00
|
|
|
|
2017-03-13 23:45:25 +01:00
|
|
|
} // namespace
|