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