Add assembler

This commit is contained in:
Kingcom 2014-07-31 14:10:36 +02:00
parent 9c77b2dfeb
commit 90eb776310
11 changed files with 1344 additions and 0 deletions

View File

@ -264,6 +264,8 @@ set(pcsx2DebugToolsSources
DebugTools/DisassemblyManager.cpp DebugTools/DisassemblyManager.cpp
DebugTools/ExpressionParser.cpp DebugTools/ExpressionParser.cpp
DebugTools/MIPSAnalyst.cpp DebugTools/MIPSAnalyst.cpp
DebugTools/MipsAssembler.cpp
DebugTools/MipsAssemblerTables.cpp
DebugTools/Breakpoints.cpp DebugTools/Breakpoints.cpp
DebugTools/SymbolMap.cpp DebugTools/SymbolMap.cpp
DebugTools/DisR3000A.cpp DebugTools/DisR3000A.cpp
@ -278,6 +280,8 @@ set(pcsx2DebugToolsHeaders
DebugTools/DisassemblyManager.h DebugTools/DisassemblyManager.h
DebugTools/ExpressionParser.h DebugTools/ExpressionParser.h
DebugTools/MIPSAnalyst.h DebugTools/MIPSAnalyst.h
DebugTools/MipsAssembler.h
DebugTools/MipsAssemblerTables.h
DebugTools/Breakpoints.h DebugTools/Breakpoints.h
DebugTools/SymbolMap.h DebugTools/SymbolMap.h
DebugTools/Debug.h DebugTools/Debug.h

View File

@ -0,0 +1,693 @@
#include "PrecompiledHeader.h"
#include "MipsAssembler.h"
// just an empty class, so that it's not necessary to remove all the calls manually
// will make it easier to update if there are changes later on
class Logger
{
public:
enum ErrorType { Warning, Error, FatalError, Notice };
static void printError(ErrorType type, const wchar_t* text, ...)
{
//
}
static void queueError(ErrorType type, const wchar_t* text, ...)
{
//
}
};
const tMipsRegister MipsRegister[] = {
{ "r0", 0, 2 }, { "zero", 0, 4}, { "$0", 0, 2 }, { "$zero", 0, 5 },
{ "at", 1, 2 }, { "r1", 1, 2 }, { "$1", 1, 2 }, { "$at", 1, 3 },
{ "v0", 2, 2 }, { "r2", 2, 2 }, { "$v0", 2, 3 },
{ "v1", 3, 2 }, { "r3", 3, 2 }, { "$v1", 3, 3 },
{ "a0", 4, 2 }, { "r4", 4, 2 }, { "$a0", 4, 3 },
{ "a1", 5, 2 }, { "r5", 5, 2 }, { "$a1", 5, 3 },
{ "a2", 6, 2 }, { "r6", 6, 2 }, { "$a2", 6, 3 },
{ "a3", 7, 2 }, { "r7", 7, 2 }, { "$a3", 7, 3 },
{ "t0", 8, 2 }, { "r8", 8, 2 }, { "$t0", 8, 3 },
{ "t1", 9, 2 }, { "r9", 9, 2 }, { "$t1", 9, 3 },
{ "t2", 10, 2 }, { "r10", 10, 3 }, { "$t2", 10, 3 },
{ "t3", 11, 2 }, { "r11", 11, 3 }, { "$t3", 11, 3 },
{ "t4", 12, 2 }, { "r12", 12, 3 }, { "$t4", 12, 3 },
{ "t5", 13, 2 }, { "r13", 13, 3 }, { "$t5", 13, 3 },
{ "t6", 14, 2 }, { "r14", 14, 3 }, { "$t6", 14, 3 },
{ "t7", 15, 2 }, { "r15", 15, 3 }, { "$t7", 15, 3 },
{ "s0", 16, 2 }, { "r16", 16, 3 }, { "$s0", 16, 3 },
{ "s1", 17, 2 }, { "r17", 17, 3 }, { "$s1", 17, 3 },
{ "s2", 18, 2 }, { "r18", 18, 3 }, { "$s2", 18, 3 },
{ "s3", 19, 2 }, { "r19", 19, 3 }, { "$s3", 19, 3 },
{ "s4", 20, 2 }, { "r20", 20, 3 }, { "$s4", 20, 3 },
{ "s5", 21, 2 }, { "r21", 21, 3 }, { "$s5", 21, 3 },
{ "s6", 22, 2 }, { "r22", 22, 3 }, { "$s6", 22, 3 },
{ "s7", 23, 2 }, { "r23", 23, 3 }, { "$s7", 23, 3 },
{ "t8", 24, 2 }, { "r24", 24, 3 }, { "$t8", 24, 3 },
{ "t9", 25, 2 }, { "r25", 25, 3 }, { "$t9", 25, 3 },
{ "k0", 26, 2 }, { "r26", 26, 3 }, { "$k0", 26, 3 },
{ "k1", 27, 2 }, { "r27", 27, 3 }, { "$k1", 27, 3 },
{ "gp", 28, 2 }, { "r28", 28, 3 }, { "$gp", 28, 3 },
{ "sp", 29, 2 }, { "r29", 29, 3 }, { "$sp", 29, 3 },
{ "fp", 30, 2 }, { "r30", 30, 3 }, { "$fp", 30, 3 },
{ "ra", 31, 2 }, { "r31", 31, 3 }, { "$ra", 31, 3 },
{ NULL, -1, 0}
};
const tMipsRegister MipsFloatRegister[] = {
{ "f0", 0, 2}, { "$f0", 0, 3 },
{ "f1", 1, 2}, { "$f1", 1, 3 },
{ "f2", 2, 2}, { "$f2", 2, 3 },
{ "f3", 3, 2}, { "$f3", 3, 3 },
{ "f4", 4, 2}, { "$f4", 4, 3 },
{ "f5", 5, 2}, { "$f5", 5, 3 },
{ "f6", 6, 2}, { "$f6", 6, 3 },
{ "f7", 7, 2}, { "$f7", 7, 3 },
{ "f8", 8, 2}, { "$f8", 8, 3 },
{ "f9", 9, 2}, { "$f9", 9, 3 },
{ "f10", 10, 3}, { "$f10", 10, 4 },
{ "f11", 11, 3}, { "$f11", 11, 4 },
{ "f12", 12, 3}, { "$f12", 12, 4 },
{ "f13", 13, 3}, { "$f13", 13, 4 },
{ "f14", 14, 3}, { "$f14", 14, 4 },
{ "f15", 15, 3}, { "$f15", 15, 4 },
{ "f16", 16, 3}, { "$f16", 16, 4 },
{ "f17", 17, 3}, { "$f17", 17, 4 },
{ "f18", 18, 3}, { "$f18", 18, 4 },
{ "f19", 19, 3}, { "$f19", 19, 4 },
{ "f20", 20, 3}, { "$f20", 20, 4 },
{ "f21", 21, 3}, { "$f21", 21, 4 },
{ "f22", 22, 3}, { "$f22", 22, 4 },
{ "f23", 23, 3}, { "$f23", 23, 4 },
{ "f24", 24, 3}, { "$f24", 24, 4 },
{ "f25", 25, 3}, { "$f25", 25, 4 },
{ "f26", 26, 3}, { "$f26", 26, 4 },
{ "f27", 27, 3}, { "$f27", 27, 4 },
{ "f28", 28, 3}, { "$f28", 28, 4 },
{ "f29", 29, 3}, { "$f29", 29, 4 },
{ "f30", 30, 3}, { "$f30", 30, 4 },
{ "f31", 31, 3}, { "$f31", 31, 4 }
};
const tMipsRegister MipsPs2Cop2FpRegister[] = {
{ "vf0", 0, 3}, { "$vf0", 0, 4 },
{ "vf1", 1, 3}, { "$vf1", 1, 4 },
{ "vf2", 2, 3}, { "$vf2", 2, 4 },
{ "vf3", 3, 3}, { "$vf3", 3, 4 },
{ "vf4", 4, 3}, { "$vf4", 4, 4 },
{ "vf5", 5, 3}, { "$vf5", 5, 4 },
{ "vf6", 6, 3}, { "$vf6", 6, 4 },
{ "vf7", 7, 3}, { "$vf7", 7, 4 },
{ "vf8", 8, 3}, { "$vf8", 8, 4 },
{ "vf9", 9, 3}, { "$vf9", 9, 4 },
{ "vf00", 0, 4}, { "$vf00", 0, 5 },
{ "vf01", 1, 4}, { "$vf01", 1, 5 },
{ "vf02", 2, 4}, { "$vf02", 2, 5 },
{ "vf03", 3, 4}, { "$vf03", 3, 5 },
{ "vf04", 4, 4}, { "$vf04", 4, 5 },
{ "vf05", 5, 4}, { "$vf05", 5, 5 },
{ "vf06", 6, 4}, { "$vf06", 6, 5 },
{ "vf07", 7, 4}, { "$vf07", 7, 5 },
{ "vf08", 8, 4}, { "$vf08", 8, 5 },
{ "vf09", 9, 4}, { "$vf09", 9, 5 },
{ "vf10", 10, 4}, { "$vf10", 10, 5 },
{ "vf11", 11, 4}, { "$vf11", 11, 5 },
{ "vf12", 12, 4}, { "$vf12", 12, 5 },
{ "vf13", 13, 4}, { "$vf13", 13, 5 },
{ "vf14", 14, 4}, { "$vf14", 14, 5 },
{ "vf15", 15, 4}, { "$vf15", 15, 5 },
{ "vf16", 16, 4}, { "$vf16", 16, 5 },
{ "vf17", 17, 4}, { "$vf17", 17, 5 },
{ "vf18", 18, 4}, { "$vf18", 18, 5 },
{ "vf19", 19, 4}, { "$vf19", 19, 5 },
{ "vf20", 20, 4}, { "$vf20", 20, 5 },
{ "vf21", 21, 4}, { "$vf21", 21, 5 },
{ "vf22", 22, 4}, { "$vf22", 22, 5 },
{ "vf23", 23, 4}, { "$vf23", 23, 5 },
{ "vf24", 24, 4}, { "$vf24", 24, 5 },
{ "vf25", 25, 4}, { "$vf25", 25, 5 },
{ "vf26", 26, 4}, { "$vf26", 26, 5 },
{ "vf27", 27, 4}, { "$vf27", 27, 5 },
{ "vf28", 28, 4}, { "$vf28", 28, 5 },
{ "vf29", 29, 4}, { "$vf29", 29, 5 },
{ "vf30", 30, 4}, { "$vf30", 30, 5 },
{ "vf31", 31, 4}, { "$vf31", 31, 5 }
};
void SplitLine(const char* Line, char* Name, char* Arguments)
{
while (*Line == ' ' || *Line == '\t') Line++;
while (*Line != ' ' && *Line != '\t')
{
if (*Line == 0)
{
*Name = 0;
*Arguments = 0;
return;
}
*Name++ = *Line++;
}
*Name = 0;
while (*Line == ' ' || *Line == '\t') Line++;
while (*Line != 0)
{
*Arguments++ = *Line++;
}
*Arguments = 0;
}
bool MipsAssembleOpcode(const char* line, DebugInterface* cpu, u32 address, u32& dest, std::string& errorText)
{
char name[64],args[256];
SplitLine(line,name,args);
CMipsInstruction opcode(cpu);
if (cpu == NULL || opcode.Load(name,args,(int)address) == false)
{
errorText = opcode.getErrorMessage();
return false;
}
if (opcode.Validate() == false)
{
errorText = "Parameter failure.";
return false;
}
opcode.Encode();
dest = opcode.getEncoding();
return true;
}
bool MipsGetRegister(const char* source, int& RetLen, MipsRegisterInfo& Result)
{
for (int z = 0; MipsRegister[z].name != NULL; z++)
{
int len = MipsRegister[z].len;
if (strncmp(MipsRegister[z].name,source,len) == 0) // okay so far
{
if (source[len] == ',' || source[len] == '\n' || source[len] == 0
|| source[len] == ')' || source[len] == '(' || source[len] == '-') // one of these has to come after a register
{
memcpy(Result.name,source,len);
Result.name[len] = 0;
Result.num = MipsRegister[z].num;
RetLen = len;
return true;
}
}
}
return false;
}
int MipsGetRegister(const char* source, int& RetLen)
{
for (int z = 0; MipsRegister[z].name != NULL; z++)
{
int len = MipsRegister[z].len;
if (strncmp(MipsRegister[z].name,source,len) == 0) // okay so far
{
if (source[len] == ',' || source[len] == '\n' || source[len] == 0
|| source[len] == ')' || source[len] == '(' || source[len] == '-') // one of these has to come after a register
{
RetLen = len;
return MipsRegister[z].num;
}
}
}
return -1;
}
bool MipsGetFloatRegister(const char* source, int& RetLen, MipsRegisterInfo& Result)
{
for (int z = 0; MipsFloatRegister[z].name != NULL; z++)
{
int len = MipsFloatRegister[z].len;
if (strncmp(MipsFloatRegister[z].name,source,len) == 0) // okay so far
{
if (source[len] == ',' || source[len] == '\n' || source[len] == 0
|| source[len] == ')' || source[len] == '(' || source[len] == '-') // one of these has to come after a register
{
memcpy(Result.name,source,len);
Result.name[len] = 0;
Result.num = MipsFloatRegister[z].num;
RetLen = len;
return true;
}
}
}
return false;
}
bool MipsGetPs2VectorRegister(const char* source, int& RetLen, MipsRegisterInfo& Result)
{
for (int z = 0; MipsPs2Cop2FpRegister[z].name != NULL; z++)
{
int len = MipsPs2Cop2FpRegister[z].len;
if (strncmp(MipsPs2Cop2FpRegister[z].name,source,len) == 0) // okay so far
{
if (source[len] == ',' || source[len] == '\n' || source[len] == 0
|| source[len] == ')' || source[len] == '(' || source[len] == '-') // one of these has to come after a register
{
memcpy(Result.name,source,len);
Result.name[len] = 0;
Result.num = MipsPs2Cop2FpRegister[z].num;
RetLen = len;
return true;
}
}
}
return false;
}
int MipsGetFloatRegister(const char* source, int& RetLen)
{
for (int z = 0; MipsFloatRegister[z].name != NULL; z++)
{
int len = MipsFloatRegister[z].len;
if (strncmp(MipsFloatRegister[z].name,source,len) == 0) // okay so far
{
if (source[len] == ',' || source[len] == '\n' || source[len] == 0
|| source[len] == ')' || source[len] == '(' || source[len] == '-') // one of these has to come after a register
{
RetLen = len;
return MipsFloatRegister[z].num;
}
}
}
return -1;
}
bool MipsCheckImmediate(const char* Source, DebugInterface* cpu, int& dest, int& RetLen)
{
char Buffer[512];
int BufferPos = 0;
int l;
if (MipsGetRegister(Source,l) != -1) // error
{
return false;
}
int SourceLen = 0;
while (true)
{
if (*Source == '\'' && *(Source+2) == '\'')
{
Buffer[BufferPos++] = *Source++;
Buffer[BufferPos++] = *Source++;
Buffer[BufferPos++] = *Source++;
SourceLen+=3;
continue;
}
if (*Source == 0 || *Source == '\n' || *Source == ',')
{
Buffer[BufferPos] = 0;
break;
}
if ( *Source == ' ' || *Source == '\t')
{
Source++;
SourceLen++;
continue;
}
if (*Source == '(') // could be part of the opcode
{
if (MipsGetRegister(Source+1,l) != -1) // end
{
Buffer[BufferPos] = 0;
break;
}
}
Buffer[BufferPos++] = *Source++;
SourceLen++;
}
if (BufferPos == 0) return false;
RetLen = SourceLen;
PostfixExpression postfix;
if (cpu->initExpression(Buffer,postfix) == false)
return false;
u64 value;
if (cpu->parseExpression(postfix,value) == false)
return false;
dest = (int) value;
return true;
}
CMipsInstruction::CMipsInstruction(DebugInterface* cpu)
{
Loaded = false;
this->cpu = cpu;
}
bool CMipsInstruction::Load(const char* Name, const char* Params, int RamPos)
{
bool paramfail = false;
NoCheckError = false;
this->RamPos = RamPos;
const MipsArchDefinition& arch = mipsArchs[MARCH_PS2];
for (int z = 0; MipsOpcodes[z].name != NULL; z++)
{
if ((MipsOpcodes[z].archs & arch.supportSets) == 0)
continue;
if ((MipsOpcodes[z].archs & arch.excludeMask) != 0)
continue;
if ((MipsOpcodes[z].flags & MO_64BIT) && !(arch.flags & MO_64BIT))
continue;
if ((MipsOpcodes[z].flags & MO_FPU) && !(arch.flags & MO_FPU))
continue;
if (parseOpcode(MipsOpcodes[z],Name) == true)
{
if (LoadEncoding(MipsOpcodes[z],Params) == true)
{
Loaded = true;
return true;
}
paramfail = true;
}
}
if (NoCheckError == false)
{
if (paramfail == true)
{
error = "Parameter failure.";
} else {
error = "Invalid opcode.";
}
}
return false;
}
bool CMipsInstruction::parseOpcode(const tMipsOpcode& SourceOpcode, const char* Line)
{
vfpuSize = -1;
const char* SourceEncoding = SourceOpcode.name;
while (*SourceEncoding != 0)
{
if (*Line == 0) return false;
switch (*SourceEncoding)
{
case 'S': // vfpu size
switch (*Line)
{
case 's':
vfpuSize = 0;
break;
case 'p':
vfpuSize = 1;
break;
case 't':
vfpuSize = 2;
break;
case 'q':
vfpuSize = 3;
break;
default:
return false;
}
SourceEncoding++;
Line++;
break;
default:
if (*SourceEncoding++ != *Line++) return false;
break;
}
}
if (*Line != 0) return false; // there's something else, bad
return true;
}
bool CMipsInstruction::LoadEncoding(const tMipsOpcode& SourceOpcode, const char* Line)
{
int RetLen;
bool Immediate = false;
immediateType = MIPS_NOIMMEDIATE;
registers.reset();
if (vfpuSize == -1)
{
if (SourceOpcode.flags & MO_VFPU_SINGLE)
vfpuSize = 0;
else if (SourceOpcode.flags & MO_VFPU_QUAD)
vfpuSize = 3;
}
const char* SourceEncoding = SourceOpcode.encoding;
const char* OriginalLine = Line;
while (*Line == ' ' || *Line == '\t') Line++;
if (!(*SourceEncoding == 0 && *Line == 0))
{
while (*SourceEncoding != 0)
{
while (*Line == ' ' || *Line == '\t') Line++;
if (*Line == 0) return false;
switch (*SourceEncoding)
{
case 'T': // float reg
if (MipsGetFloatRegister(Line,RetLen,registers.frt) == false) return false;
Line += RetLen;
SourceEncoding++;
break;
case 'D': // float reg
if (MipsGetFloatRegister(Line,RetLen,registers.frd) == false) return false;
Line += RetLen;
SourceEncoding++;
break;
case 'S': // float reg
if (MipsGetFloatRegister(Line,RetLen,registers.frs) == false) return false;
Line += RetLen;
SourceEncoding++;
break;
case 't':
if (MipsGetRegister(Line,RetLen,registers.grt) == false) return false;
Line += RetLen;
SourceEncoding++;
break;
case 'd':
if (MipsGetRegister(Line,RetLen,registers.grd) == false) return false;
Line += RetLen;
SourceEncoding++;
break;
case 's':
if (MipsGetRegister(Line,RetLen,registers.grs) == false) return false;
Line += RetLen;
SourceEncoding++;
break;
case 'V': // ps2 vector registers
switch (*(SourceEncoding+1))
{
case 's':
if (MipsGetPs2VectorRegister(Line,RetLen,registers.ps2vrs) == false) return false;
Line += RetLen;
break;
case 't':
if (MipsGetPs2VectorRegister(Line,RetLen,registers.ps2vrt) == false) return false;
Line += RetLen;
break;
case 'd':
if (MipsGetPs2VectorRegister(Line,RetLen,registers.ps2vrd) == false) return false;
Line += RetLen;
break;
default:
return false;
}
SourceEncoding += 2;
break;
case 'a': // 5 bit immediate
if (MipsCheckImmediate(Line,cpu,immediate.originalValue,RetLen) == false) return false;
immediateType = MIPS_IMMEDIATE5;
Line += RetLen;
SourceEncoding++;
break;
case 'i': // 16 bit immediate
if (MipsCheckImmediate(Line,cpu,immediate.originalValue,RetLen) == false) return false;
immediateType = MIPS_IMMEDIATE16;
Line += RetLen;
SourceEncoding++;
break;
case 'b': // 20 bit immediate
if (MipsCheckImmediate(Line,cpu,immediate.originalValue,RetLen) == false) return false;
immediateType = MIPS_IMMEDIATE20;
Line += RetLen;
SourceEncoding++;
break;
case 'I': // 32 bit immediate
if (MipsCheckImmediate(Line,cpu,immediate.originalValue,RetLen) == false) return false;
immediateType = MIPS_IMMEDIATE26;
Line += RetLen;
SourceEncoding++;
break;
case 'r': // forced register
if (MipsGetRegister(Line,RetLen) != *(SourceEncoding+1)) return false;
Line += RetLen;
SourceEncoding += 2;
break;
case '/': // forced letter
SourceEncoding++; // fallthrough
default: // everything else
if (*SourceEncoding++ != *Line++) return false;
break;
}
}
}
while (*Line == ' ' || *Line == '\t') Line++;
if (*Line != 0) return false; // there's something else, bad
// opcode is ok - now set all flags
Opcode = SourceOpcode;
immediate.value = immediate.originalValue;
setOmittedRegisters();
return true;
}
void CMipsInstruction::setOmittedRegisters()
{
// copy over omitted registers
if (Opcode.flags & MO_RSD)
registers.grd = registers.grs;
if (Opcode.flags & MO_RST)
registers.grt = registers.grs;
if (Opcode.flags & MO_RDT)
registers.grt = registers.grd;
if (Opcode.flags & MO_FRSD)
registers.frd = registers.frs;
}
int getImmediateBits(MipsImmediateType type)
{
switch (type)
{
case MIPS_IMMEDIATE5:
return 5;
case MIPS_IMMEDIATE16:
return 16;
case MIPS_IMMEDIATE20:
return 20;
case MIPS_IMMEDIATE26:
return 26;
default:
return 0;
}
}
bool CMipsInstruction::Validate()
{
if (RamPos % 4)
{
Logger::queueError(Logger::Error,L"opcode not aligned to word boundary");
return false;
}
// check immediates
if (immediateType != MIPS_NOIMMEDIATE)
{
immediate.originalValue = immediate.value;
if (Opcode.flags & MO_IMMALIGNED) // immediate must be aligned
{
if (immediate.value % 4)
{
Logger::queueError(Logger::Error,L"Immediate must be word aligned",immediate.value);
return false;
}
}
if (Opcode.flags & MO_IPCA) // absolute value >> 2)
{
immediate.value = (immediate.value >> 2) & 0x3FFFFFF;
} else if (Opcode.flags & MO_IPCR) // relative 16 bit value
{
int num = (immediate.value-RamPos-4);
if (num > 0x20000 || num < (-0x20000))
{
Logger::queueError(Logger::Error,L"Branch target %08X out of range",immediate.value);
return false;
}
immediate.value = num >> 2;
}
int immediateBits = getImmediateBits(immediateType);
unsigned int mask = (0xFFFFFFFF << (32-immediateBits)) >> (32-immediateBits);
int digits = (immediateBits+3) / 4;
if ((unsigned int)std::abs(immediate.value) > mask)
{
Logger::queueError(Logger::Error,L"Immediate value %0*X out of range",digits,immediate.value);
return false;
}
immediate.value &= mask;
}
return true;
}
void CMipsInstruction::encodeNormal()
{
encoding = Opcode.destencoding;
if (registers.grs.num != -1) encoding |= MIPS_RS(registers.grs.num); // source reg
if (registers.grt.num != -1) encoding |= MIPS_RT(registers.grt.num); // target reg
if (registers.grd.num != -1) encoding |= MIPS_RD(registers.grd.num); // dest reg
if (registers.frt.num != -1) encoding |= MIPS_FT(registers.frt.num); // float target reg
if (registers.frs.num != -1) encoding |= MIPS_FS(registers.frs.num); // float source reg
if (registers.frd.num != -1) encoding |= MIPS_FD(registers.frd.num); // float dest reg
if (registers.ps2vrt.num != -1) encoding |= (registers.ps2vrt.num << 16); // ps2 vector target reg
if (registers.ps2vrs.num != -1) encoding |= (registers.ps2vrs.num << 21); // ps2 vector source reg
if (registers.ps2vrd.num != -1) encoding |= (registers.ps2vrd.num << 6); // ps2 vector dest reg
switch (immediateType)
{
case MIPS_IMMEDIATE5:
case MIPS_IMMEDIATE20:
encoding |= immediate.value << 6;
break;
case MIPS_IMMEDIATE16:
case MIPS_IMMEDIATE26:
encoding |= immediate.value;
break;
}
}
void CMipsInstruction::Encode()
{
encodeNormal();
}

View File

@ -0,0 +1,80 @@
#pragma once
#include "MipsAssemblerTables.h"
#include "DebugInterface.h"
enum MipsImmediateType { MIPS_NOIMMEDIATE, MIPS_IMMEDIATE5,
MIPS_IMMEDIATE16, MIPS_IMMEDIATE20, MIPS_IMMEDIATE26 };
enum MipsArchType { MARCH_PSX = 0, MARCH_N64, MARCH_PS2, MARCH_PSP, MARCH_INVALID };
typedef struct {
const char* name;
short num;
short len;
} tMipsRegister;
typedef struct {
char name[5];
short num;
} MipsRegisterInfo;
struct MipsImmediate
{
int value;
int originalValue;
};
struct MipsOpcodeRegisters {
MipsRegisterInfo grs; // general source reg
MipsRegisterInfo grt; // general target reg
MipsRegisterInfo grd; // general dest reg
MipsRegisterInfo frs; // float source reg
MipsRegisterInfo frt; // float target reg
MipsRegisterInfo frd; // float dest reg
MipsRegisterInfo ps2vrs; // ps2 vector source reg
MipsRegisterInfo ps2vrt; // ps2 vector target reg
MipsRegisterInfo ps2vrd; // ps2 vector dest reg
void reset()
{
grs.num = grt.num = grd.num = -1;
frs.num = frt.num = frd.num = -1;
ps2vrs.num = ps2vrt.num = ps2vrd.num = -1;
}
};
class CMipsInstruction
{
public:
CMipsInstruction(DebugInterface* cpu);
bool Load(const char* Name, const char* Params, int RamPos);
virtual bool Validate();
virtual void Encode();
u32 getEncoding() { return encoding; };
std::string getErrorMessage() { return error; };
private:
void encodeNormal();
bool parseOpcode(const tMipsOpcode& SourceOpcode, const char* Line);
bool LoadEncoding(const tMipsOpcode& SourceOpcode, const char* Line);
void setOmittedRegisters();
tMipsOpcode Opcode;
bool NoCheckError;
bool Loaded;
int RamPos;
// opcode variables
MipsOpcodeRegisters registers;
MipsImmediateType immediateType;
MipsImmediate immediate;
int vfpuSize;
DebugInterface* cpu;
u32 encoding;
std::string error;
};
bool MipsAssembleOpcode(const char* line, DebugInterface* cpu, u32 address, u32& dest, std::string& errorText);

View File

@ -0,0 +1,441 @@
#include "PrecompiledHeader.h"
#include "MipsAssemblerTables.h"
/* Placeholders for encoding
s source register
d destination register
t target register
S float source reg
D float dest reg
T float traget reg
i 16 bit immediate value
I 32 bit immediate value
u Shifted 16 bit immediate (upper)
n negative 16 bit immediate (for subi/u aliases)
b 26 bit immediate
a 5 bit immediate
*/
// NOTE: This tables also contains opcodes that aren't available on PS2. This was done
// because it's shared between multiple projects, and manually removing the opcodes every
// time is error prone and makes it harder to maintain. They aren't accessible, so they
// cause no harm besides appearing here.
const tMipsOpcode MipsOpcodes[] = {
// 31---------26---------------------------------------------------0
// | opcode | |
// ------6----------------------------------------------------------
// |--000--|--001--|--010--|--011--|--100--|--101--|--110--|--111--| lo
// 000 | *1 | *2 | J | JAL | BEQ | BNE | BLEZ | BGTZ | 00..07
// 001 | ADDI | ADDIU | SLTI | SLTIU | ANDI | ORI | XORI | LUI | 08..0F
// 010 | *3 | *4 | --- | --- | BEQL | BNEL | BLEZL | BGTZL | 10..17
// 011 | DADDI | DADDIU| LDL | LDR | --- | --- | LQ | SQ | 18..1F
// 100 | LB | LH | LWL | LW | LBU | LHU | LWR | LWU | 20..27
// 101 | SB | SH | SWL | SW | SDL | SDR | SWR | CACHE | 28..2F
// 110 | LL | LWC1 | LV.S | --- | LLD | ULV.Q | LV.Q | LD | 30..37
// 111 | SC | SWC1 | SV.S | --- | SCD | USV.Q | SV.Q | SD | 38..3F
// hi |-------|-------|-------|-------|-------|-------|-------|-------|
// *1 = SPECIAL *2 = REGIMM *3 = COP0 *4 = COP1
{ "j", "I", MIPS_OP(0x02), MA_MIPS1, MO_IPCA|MO_DELAY|MO_NODELAYSLOT },
{ "b", "I", MIPS_OP(0x02), MA_MIPS1, MO_IPCA|MO_DELAY|MO_NODELAYSLOT },
{ "jal", "I", MIPS_OP(0x03), MA_MIPS1, MO_IPCA|MO_DELAY|MO_NODELAYSLOT },
{ "beq", "s,t,i", MIPS_OP(0x04), MA_MIPS1, MO_IPCR|MO_DELAY|MO_NODELAYSLOT },
{ "beqz", "s,i", MIPS_OP(0x04), MA_MIPS1, MO_IPCR|MO_DELAY|MO_NODELAYSLOT },
{ "bne", "s,t,i", MIPS_OP(0x05), MA_MIPS1, MO_IPCR|MO_DELAY|MO_NODELAYSLOT },
{ "bnez", "s,i", MIPS_OP(0x05), MA_MIPS1, MO_IPCR|MO_DELAY|MO_NODELAYSLOT },
{ "blez", "s,i", MIPS_OP(0x06), MA_MIPS1, MO_IPCR|MO_DELAY|MO_NODELAYSLOT },
{ "bgtz", "s,i", MIPS_OP(0x07), MA_MIPS1, MO_IPCR|MO_DELAY|MO_NODELAYSLOT },
{ "addi", "t,s,i", MIPS_OP(0x08), MA_MIPS1, 0 },
{ "addi", "s,i", MIPS_OP(0x08), MA_MIPS1, MO_RST },
{ "addiu", "t,s,i", MIPS_OP(0x09), MA_MIPS1, 0 },
{ "addiu", "s,i", MIPS_OP(0x09), MA_MIPS1, MO_RST },
{ "slti", "t,s,i", MIPS_OP(0x0A), MA_MIPS1, 0 },
{ "slti", "s,i", MIPS_OP(0x0A), MA_MIPS1, MO_RST },
{ "sltiu", "t,s,i", MIPS_OP(0x0B), MA_MIPS1, 0 },
{ "sltiu", "s,i", MIPS_OP(0x0B), MA_MIPS1, MO_RST },
{ "andi", "t,s,i", MIPS_OP(0x0C), MA_MIPS1, 0 },
{ "andi", "s,i", MIPS_OP(0x0C), MA_MIPS1, MO_RST },
{ "ori", "t,s,i", MIPS_OP(0x0D), MA_MIPS1, 0 },
{ "ori", "s,i", MIPS_OP(0x0D), MA_MIPS1, MO_RST },
{ "xori", "t,s,i", MIPS_OP(0x0E), MA_MIPS1, 0 },
{ "xori", "s,i", MIPS_OP(0x0E), MA_MIPS1, MO_RST },
{ "lui", "t,i", MIPS_OP(0x0F), MA_MIPS1, 0 },
{ "beql", "s,t,i", MIPS_OP(0x14), MA_MIPS2, MO_IPCR|MO_DELAY|MO_NODELAYSLOT },
{ "beqzl", "s,i", MIPS_OP(0x14), MA_MIPS2, MO_IPCR|MO_DELAY|MO_NODELAYSLOT },
{ "bnel", "s,t,i", MIPS_OP(0x15), MA_MIPS2, MO_IPCR|MO_DELAY|MO_NODELAYSLOT },
{ "bnezl", "s,i", MIPS_OP(0x15), MA_MIPS2, MO_IPCR|MO_DELAY|MO_NODELAYSLOT },
{ "blezl", "s,i", MIPS_OP(0x16), MA_MIPS2, MO_IPCR|MO_DELAY|MO_NODELAYSLOT },
{ "bgtzl", "s,i", MIPS_OP(0x17), MA_MIPS2, MO_IPCR|MO_DELAY|MO_NODELAYSLOT },
{ "daddi", "t,s,i", MIPS_OP(0x18), MA_MIPS3, MO_64BIT },
{ "daddi", "s,i", MIPS_OP(0x18), MA_MIPS3, MO_64BIT|MO_RST },
{ "daddiu", "t,s,i", MIPS_OP(0x19), MA_MIPS3, MO_64BIT },
{ "daddiu", "s,i", MIPS_OP(0x19), MA_MIPS3, MO_64BIT|MO_RST },
{ "ldl", "t,i(s)", MIPS_OP(0x1A), MA_MIPS3, MO_64BIT|MO_DELAYRT },
{ "ldl", "t,(s)", MIPS_OP(0x1A), MA_MIPS3, MO_64BIT|MO_DELAYRT },
{ "ldr", "t,i(s)", MIPS_OP(0x1B), MA_MIPS3, MO_64BIT|MO_DELAYRT|MO_IGNORERTD },
{ "ldr", "t,(s)", MIPS_OP(0x1B), MA_MIPS3, MO_64BIT|MO_DELAYRT|MO_IGNORERTD },
{ "lq", "t,i(s)", MIPS_OP(0x1E), MA_MIPS1, MO_DELAYRT },
{ "sq", "t,i(s)", MIPS_OP(0x1F), MA_MIPS1, MO_DELAYRT },
{ "lb", "t,i(s)", MIPS_OP(0x20), MA_MIPS1, MO_DELAYRT },
{ "lb", "t,(s)", MIPS_OP(0x20), MA_MIPS1, MO_DELAYRT },
{ "lh", "t,i(s)", MIPS_OP(0x21), MA_MIPS1, MO_DELAYRT },
{ "lh", "t,(s)", MIPS_OP(0x21), MA_MIPS1, MO_DELAYRT },
{ "lwl", "t,i(s)", MIPS_OP(0x22), MA_MIPS1, MO_DELAYRT },
{ "lwl", "t,(s)", MIPS_OP(0x22), MA_MIPS1, MO_DELAYRT },
{ "lw", "t,i(s)", MIPS_OP(0x23), MA_MIPS1, MO_DELAYRT },
{ "lw", "t,(s)", MIPS_OP(0x23), MA_MIPS1, MO_DELAYRT },
{ "lbu", "t,i(s)", MIPS_OP(0x24), MA_MIPS1, MO_DELAYRT },
{ "lbu", "t,(s)", MIPS_OP(0x24), MA_MIPS1, MO_DELAYRT },
{ "lhu", "t,i(s)", MIPS_OP(0x25), MA_MIPS1, MO_DELAYRT },
{ "lhu", "t,(s)", MIPS_OP(0x25), MA_MIPS1, MO_DELAYRT },
{ "lwr", "t,i(s)", MIPS_OP(0x26), MA_MIPS1, MO_DELAYRT|MO_IGNORERTD },
{ "lwr", "t,(s)", MIPS_OP(0x26), MA_MIPS1, MO_DELAYRT|MO_IGNORERTD },
{ "lwu", "t,i(s)", MIPS_OP(0x27), MA_MIPS3, MO_64BIT|MO_DELAYRT },
{ "lwu", "t,(s)", MIPS_OP(0x27), MA_MIPS3, MO_64BIT|MO_DELAYRT },
{ "sb", "t,i(s)", MIPS_OP(0x28), MA_MIPS1, 0 },
{ "sb", "t,(s)", MIPS_OP(0x28), MA_MIPS1, 0 },
{ "sh", "t,i(s)", MIPS_OP(0x29), MA_MIPS1, 0 },
{ "sh", "t,(s)", MIPS_OP(0x29), MA_MIPS1, 0 },
{ "swl", "t,i(s)", MIPS_OP(0x2A), MA_MIPS1, 0 },
{ "swl", "t,(s)", MIPS_OP(0x2A), MA_MIPS1, 0 },
{ "sw", "t,i(s)", MIPS_OP(0x2B), MA_MIPS1, 0 },
{ "sw", "t,(s)", MIPS_OP(0x2B), MA_MIPS1, 0 },
{ "sdl", "t,i(s)", MIPS_OP(0x2C), MA_MIPS3, MO_64BIT|MO_DELAYRT },
{ "sdl", "t,(s)", MIPS_OP(0x2C), MA_MIPS3, MO_64BIT|MO_DELAYRT },
{ "sdr", "t,i(s)", MIPS_OP(0x2D), MA_MIPS3, MO_64BIT|MO_DELAYRT|MO_IGNORERTD },
{ "sdr", "t,(s)", MIPS_OP(0x2D), MA_MIPS3, MO_64BIT|MO_DELAYRT|MO_IGNORERTD },
{ "swr", "t,i(s)", MIPS_OP(0x2E), MA_MIPS1, 0 },
{ "swr", "t,(s)", MIPS_OP(0x2E), MA_MIPS1, 0 },
{ "cache", "t,i(s)", MIPS_OP(0x2F), MA_PS2, 0 },
{ "ll", "t,i(s)", MIPS_OP(0x30), MA_MIPS2, MO_DELAYRT },
{ "ll", "t,(s)", MIPS_OP(0x30), MA_MIPS2, MO_DELAYRT },
{ "lwc1", "T,i(s)", MIPS_OP(0x31), MA_MIPS1, 0 },
{ "lwc1", "T,(s)", MIPS_OP(0x31), MA_MIPS1, 0 },
{ "lv.s", "vt,i(s)", MIPS_OP(0x32), MA_PSP, MO_VFPU_SINGLE|MO_VFPU_MIXED|MO_IMMALIGNED },
{ "lv.s", "vt,(s)", MIPS_OP(0x32), MA_PSP, MO_VFPU_SINGLE|MO_VFPU_MIXED },
{ "lld", "t,i(s)", MIPS_OP(0x34), MA_MIPS3, MO_64BIT|MO_DELAYRT },
{ "lld", "t,(s)", MIPS_OP(0x34), MA_MIPS3, MO_64BIT|MO_DELAYRT },
{ "ulv.q", "vt,i(s)", MIPS_OP(0x35), MA_PSP, MO_VFPU_QUAD|MO_VFPU_MIXED|MO_IMMALIGNED },
{ "ulv.q", "vt,(s)", MIPS_OP(0x35), MA_PSP, MO_VFPU_QUAD|MO_VFPU_MIXED },
{ "lvl.q", "vt,i(s)", MIPS_OP(0x35), MA_PSP, MO_VFPU_QUAD|MO_VFPU_MIXED|MO_VFPU_6BIT|MO_IMMALIGNED },
{ "lvl.q", "vt,(s)", MIPS_OP(0x35), MA_PSP, MO_VFPU_QUAD|MO_VFPU_MIXED|MO_VFPU_6BIT },
{ "lvr.q", "vt,i(s)", MIPS_OP(0x35)|0x02, MA_PSP, MO_VFPU_QUAD|MO_VFPU_MIXED|MO_VFPU_6BIT|MO_IMMALIGNED },
{ "lvr.q", "vt,(s)", MIPS_OP(0x35)|0x02, MA_PSP, MO_VFPU_QUAD|MO_VFPU_MIXED|MO_VFPU_6BIT },
{ "lv.q", "vt,i(s)", MIPS_OP(0x36), MA_PSP, MO_VFPU_QUAD|MO_VFPU_MIXED|MO_VFPU_6BIT|MO_IMMALIGNED },
{ "lv.q", "vt,(s)", MIPS_OP(0x36), MA_PSP, MO_VFPU_QUAD|MO_VFPU_MIXED|MO_VFPU_6BIT },
{ "lqc2", "Vt,i(s)", MIPS_OP(0x36), MA_PS2, MO_DELAYRT },
{ "ld", "t,i(s)", MIPS_OP(0x37), MA_MIPS3, MO_64BIT|MO_DELAYRT },
{ "ld", "t,(s)", MIPS_OP(0x37), MA_MIPS3, MO_64BIT|MO_DELAYRT },
{ "sc", "t,i(s)", MIPS_OP(0x38), MA_MIPS2, 0 },
{ "sc", "t,(s)", MIPS_OP(0x38), MA_MIPS2, 0 },
{ "swc1", "T,i(s)", MIPS_OP(0x39), MA_MIPS1, 0 },
{ "swc1", "T,(s)", MIPS_OP(0x39), MA_MIPS1, 0 },
{ "sv.s", "vt,i(s)", MIPS_OP(0x3A), MA_PSP, MO_VFPU_SINGLE|MO_VFPU_MIXED|MO_IMMALIGNED },
{ "sv.s", "vt,(s)", MIPS_OP(0x3A), MA_PSP, MO_VFPU_SINGLE|MO_VFPU_MIXED },
{ "scd", "t,i(s)", MIPS_OP(0x3C), MA_MIPS3, MO_64BIT|MO_DELAYRT },
{ "scd", "t,(s)", MIPS_OP(0x3C), MA_MIPS3, MO_64BIT|MO_DELAYRT },
{ "usv.q", "vt,i(s)", MIPS_OP(0x3D), MA_PSP, MO_VFPU_QUAD|MO_VFPU_MIXED|MO_IMMALIGNED },
{ "usv.q", "vt,(s)", MIPS_OP(0x3D), MA_PSP, MO_VFPU_QUAD|MO_VFPU_MIXED },
{ "svl.q", "vt,i(s)", MIPS_OP(0x3D), MA_PSP, MO_VFPU_QUAD|MO_VFPU_MIXED|MO_VFPU_6BIT|MO_IMMALIGNED },
{ "svl.q", "vt,(s)", MIPS_OP(0x3D), MA_PSP, MO_VFPU_QUAD|MO_VFPU_MIXED|MO_VFPU_6BIT },
{ "svr.q", "vt,i(s)", MIPS_OP(0x3D)|0x02, MA_PSP, MO_VFPU_QUAD|MO_VFPU_MIXED|MO_VFPU_6BIT|MO_IMMALIGNED },
{ "svr.q", "vt,(s)", MIPS_OP(0x3D)|0x02, MA_PSP, MO_VFPU_QUAD|MO_VFPU_MIXED|MO_VFPU_6BIT },
{ "sv.q", "vt,i(s)", MIPS_OP(0x3E), MA_PSP, MO_VFPU_QUAD|MO_VFPU_MIXED|MO_VFPU_6BIT|MO_IMMALIGNED },
{ "sv.q", "vt,(s)", MIPS_OP(0x3E), MA_PSP, MO_VFPU_QUAD|MO_VFPU_MIXED|MO_VFPU_6BIT },
{ "sv.q", "vt,i(s),/w/b", MIPS_OP(0x3E)|0x02, MA_PSP, MO_VFPU_QUAD|MO_VFPU_MIXED|MO_VFPU_6BIT|MO_IMMALIGNED },
{ "sv.q", "vt,(s),/w/b", MIPS_OP(0x3E)|0x02, MA_PSP, MO_VFPU_QUAD|MO_VFPU_MIXED|MO_VFPU_6BIT },
{ "sqc2", "Vt,i(s)", MIPS_OP(0x3E), MA_PS2, MO_DELAYRT },
{ "sd", "t,i(s)", MIPS_OP(0x3F), MA_MIPS3, MO_64BIT|MO_DELAYRT },
{ "sd", "t,(s)", MIPS_OP(0x3F), MA_MIPS3, MO_64BIT|MO_DELAYRT },
// 31---------26------------------------------------------5--------0
// |= SPECIAL| | function|
// ------6----------------------------------------------------6-----
// |--000--|--001--|--010--|--011--|--100--|--101--|--110--|--111--| lo
// 000 | SLL | --- | SRL*1 | SRA | SLLV | --- | SRLV*2| SRAV | 00..07
// 001 | JR | JALR | MOVZ | MOVN |SYSCALL| BREAK | --- | SYNC | 08..0F
// 010 | MFHI | MTHI | MFLO | MTLO | DSLLV | --- | *3 | *4 | 10..17
// 011 | MULT | MULTU | DIV | DIVU | MADD | MADDU | ---- | ----- | 18..1F
// 100 | ADD | ADDU | SUB | SUBU | AND | OR | XOR | NOR | 20..27
// 101 | mfsa | mtsa | SLT | SLTU | *5 | *6 | *7 | *8 | 28..2F
// 110 | TGE | TGEU | TLT | TLTU | TEQ | --- | TNE | --- | 30..37
// 111 | dsll | --- | dsrl | dsra |dsll32 | --- |dsrl32 |dsra32 | 38..3F
// hi |-------|-------|-------|-------|-------|-------|-------|-------|
// *1: rotr when rs = 1 (PSP only) *2: rotrv when sa = 1 (PSP only)
// *3: dsrlv on PS2, clz on PSP *4: dsrav on PS2, clo on PSP
// *5: dadd on PS2, max on PSP *6: daddu on PS2, min on PSP
// *7: dsub on PS2, msub on PSP *8: dsubu on PS2, msubu on PSP
{ "sll", "d,t,a", MIPS_SPECIAL(0x00), MA_MIPS1, 0 },
{ "sll", "d,a", MIPS_SPECIAL(0x00), MA_MIPS1, MO_RDT },
{ "nop", "", MIPS_SPECIAL(0x00), MA_MIPS1, 0 },
{ "srl", "d,t,a", MIPS_SPECIAL(0x02), MA_MIPS1, 0 },
{ "srl", "d,a", MIPS_SPECIAL(0x02), MA_MIPS1, MO_RDT },
{ "rotr", "d,t,a", MIPS_SPECIAL(0x02)|MIPS_RS(1), MA_PSP, 0 },
{ "rotr", "d,a", MIPS_SPECIAL(0x02)|MIPS_RS(1), MA_PSP, MO_RDT },
{ "sra", "d,t,a", MIPS_SPECIAL(0x03), MA_MIPS1, 0 },
{ "sra", "d,a", MIPS_SPECIAL(0x03), MA_MIPS1, MO_RDT },
{ "sllv", "d,t,s", MIPS_SPECIAL(0x04), MA_MIPS1, 0 },
{ "sllv", "d,s", MIPS_SPECIAL(0x04), MA_MIPS1, MO_RDT },
{ "srlv", "d,t,s", MIPS_SPECIAL(0x06), MA_MIPS1, 0 },
{ "srlv", "d,s", MIPS_SPECIAL(0x06), MA_MIPS1, MO_RDT },
{ "rotrv", "d,t,s", MIPS_SPECIAL(0x06)|MIPS_SA(1), MA_PSP, 0 },
{ "rotrv", "d,s", MIPS_SPECIAL(0x06)|MIPS_SA(1), MA_PSP, MO_RDT },
{ "srav", "d,t,s", MIPS_SPECIAL(0x07), MA_MIPS1, 0 },
{ "srav", "d,s", MIPS_SPECIAL(0x07), MA_MIPS1, MO_RDT },
{ "jr", "s", MIPS_SPECIAL(0x08), MA_MIPS1, MO_DELAY|MO_NODELAYSLOT },
{ "jalr", "s,d", MIPS_SPECIAL(0x09), MA_MIPS1, MO_DELAY|MO_NODELAYSLOT },
{ "jalr", "s", MIPS_SPECIAL(0x09)|MIPS_RD(31), MA_MIPS1, MO_DELAY|MO_NODELAYSLOT },
{ "movz", "d,s,t", MIPS_SPECIAL(0x0A), MA_MIPS4|MA_PS2|MA_PSP, 0 },
{ "movn", "d,s,t", MIPS_SPECIAL(0x0B), MA_MIPS4|MA_PS2|MA_PSP, 0 },
{ "syscall","b", MIPS_SPECIAL(0x0C), MA_MIPS1, MO_NODELAYSLOT },
{ "break", "b", MIPS_SPECIAL(0x0D), MA_MIPS1, MO_NODELAYSLOT },
{ "sync", "", MIPS_SPECIAL(0x0F), MA_MIPS2, 0 },
{ "mfhi", "d", MIPS_SPECIAL(0x10), MA_MIPS1, 0 },
{ "mthi", "s", MIPS_SPECIAL(0x11), MA_MIPS1, 0 },
{ "mflo", "d", MIPS_SPECIAL(0x12), MA_MIPS1, 0 },
{ "mtlo", "s", MIPS_SPECIAL(0x13), MA_MIPS1, 0 },
{ "dsllv", "d,t,s", MIPS_SPECIAL(0x14), MA_MIPS3, MO_64BIT },
{ "dsllv", "d,s", MIPS_SPECIAL(0x14), MA_MIPS3, MO_64BIT },
{ "dsrlv", "d,t,s", MIPS_SPECIAL(0x16), MA_MIPS3, MO_64BIT },
{ "dsrlv", "d,s", MIPS_SPECIAL(0x16), MA_MIPS3, MO_64BIT|MO_RDT },
{ "clz", "d,s", MIPS_SPECIAL(0x16), MA_PSP, 0 },
{ "dsrav", "d,t,s", MIPS_SPECIAL(0x17), MA_MIPS3, MO_64BIT },
{ "dsrav", "d,s", MIPS_SPECIAL(0x17), MA_MIPS3, MO_64BIT|MO_RDT },
{ "clo", "d,s", MIPS_SPECIAL(0x17), MA_PSP, 0 },
{ "mult", "s,t", MIPS_SPECIAL(0x18), MA_MIPS1, 0 },
{ "mult", "r\x0,s,t", MIPS_SPECIAL(0x18), MA_MIPS1, 0 },
{ "multu", "s,t", MIPS_SPECIAL(0x19), MA_MIPS1, 0 },
{ "multu", "r\x0,s,t", MIPS_SPECIAL(0x19), MA_MIPS1, 0 },
{ "div", "s,t", MIPS_SPECIAL(0x1A), MA_MIPS1, 0 },
{ "div", "r\x0,s,t", MIPS_SPECIAL(0x1A), MA_MIPS1, 0 },
{ "divu", "s,t", MIPS_SPECIAL(0x1B), MA_MIPS1, 0 },
{ "divu", "r\x0,s,t", MIPS_SPECIAL(0x1B), MA_MIPS1, 0 },
{ "dmult", "s,t", MIPS_SPECIAL(0x1C), MA_MIPS3|MA_EXPS2, MO_64BIT },
{ "dmult", "r\x0,s,t", MIPS_SPECIAL(0x1C), MA_MIPS3|MA_EXPS2, MO_64BIT },
{ "madd", "s,t", MIPS_SPECIAL(0x1C), MA_PSP, 0 },
{ "dmultu", "s,t", MIPS_SPECIAL(0x1D), MA_MIPS3|MA_EXPS2, MO_64BIT },
{ "dmultu", "r\x0,s,t", MIPS_SPECIAL(0x1D), MA_MIPS3|MA_EXPS2, MO_64BIT },
{ "maddu", "s,t", MIPS_SPECIAL(0x1D), MA_PSP, 0 },
{ "ddiv", "s,t", MIPS_SPECIAL(0x1E), MA_MIPS3|MA_EXPS2, MO_64BIT },
{ "ddiv", "r\x0,s,t", MIPS_SPECIAL(0x1E), MA_MIPS3|MA_EXPS2, MO_64BIT },
{ "ddivu", "s,t", MIPS_SPECIAL(0x1F), MA_MIPS3|MA_EXPS2, MO_64BIT },
{ "ddivu", "r\x0,s,t", MIPS_SPECIAL(0x1F), MA_MIPS3|MA_EXPS2, MO_64BIT },
{ "add", "d,s,t", MIPS_SPECIAL(0x20), MA_MIPS1, 0 },
{ "add", "s,t", MIPS_SPECIAL(0x20), MA_MIPS1, MO_RSD },
{ "addu", "d,s,t", MIPS_SPECIAL(0x21), MA_MIPS1, 0 },
{ "addu", "s,t", MIPS_SPECIAL(0x21), MA_MIPS1, MO_RSD },
{ "move", "d,s", MIPS_SPECIAL(0x21), MA_MIPS1, 0 },
{ "sub", "d,s,t", MIPS_SPECIAL(0x22), MA_MIPS1, 0 },
{ "sub", "s,t", MIPS_SPECIAL(0x22), MA_MIPS1, MO_RSD },
{ "neg", "d,t", MIPS_SPECIAL(0x22), MA_MIPS1, 0 },
{ "subu", "d,s,t", MIPS_SPECIAL(0x23), MA_MIPS1, 0 },
{ "subu", "s,t", MIPS_SPECIAL(0x23), MA_MIPS1, MO_RSD },
{ "negu", "d,t", MIPS_SPECIAL(0x23), MA_MIPS1, 0 },
{ "and", "d,s,t", MIPS_SPECIAL(0x24), MA_MIPS1, 0 },
{ "and", "s,t", MIPS_SPECIAL(0x24), MA_MIPS1, MO_RSD },
{ "or", "d,s,t", MIPS_SPECIAL(0x25), MA_MIPS1, 0 },
{ "or", "s,t", MIPS_SPECIAL(0x25), MA_MIPS1, MO_RSD },
{ "xor", "d,s,t", MIPS_SPECIAL(0x26), MA_MIPS1, 0 },
{ "eor", "d,s,t", MIPS_SPECIAL(0x26), MA_MIPS1, 0 },
{ "xor", "s,t", MIPS_SPECIAL(0x26), MA_MIPS1, MO_RSD },
{ "eor", "s,t", MIPS_SPECIAL(0x26), MA_MIPS1, MO_RSD },
{ "nor", "d,s,t", MIPS_SPECIAL(0x27), MA_MIPS1, 0 },
{ "nor", "s,t", MIPS_SPECIAL(0x27), MA_MIPS1, MO_RSD },
{ "mfsa", "d", MIPS_SPECIAL(0x28), MA_PS2, 0 },
{ "mtsa", "s", MIPS_SPECIAL(0x29), MA_PS2, 0 },
{ "slt", "d,s,t", MIPS_SPECIAL(0x2A), MA_MIPS1, 0 },
{ "slt", "s,t", MIPS_SPECIAL(0x2A), MA_MIPS1, MO_RSD},
{ "sltu", "d,s,t", MIPS_SPECIAL(0x2B), MA_MIPS1, 0 },
{ "sltu", "s,t", MIPS_SPECIAL(0x2B), MA_MIPS1, MO_RSD },
{ "dadd", "d,s,t", MIPS_SPECIAL(0x2C), MA_MIPS3, MO_64BIT },
{ "max", "d,s,t", MIPS_SPECIAL(0x2C), MA_PSP, 0 },
{ "daddu", "d,s,t", MIPS_SPECIAL(0x2D), MA_MIPS3, MO_64BIT },
{ "dmove", "d,s", MIPS_SPECIAL(0x2D), MA_MIPS3, MO_64BIT },
{ "min", "d,s,t", MIPS_SPECIAL(0x2D), MA_PSP, 0 },
{ "dsub", "d,s,t", MIPS_SPECIAL(0x2E), MA_MIPS3, MO_64BIT },
{ "msub", "s,t", MIPS_SPECIAL(0x2E), MA_PSP, 0 },
{ "dsubu", "d,s,t", MIPS_SPECIAL(0x2F), MA_MIPS3, MO_64BIT },
{ "msubu", "s,t", MIPS_SPECIAL(0x2F), MA_PSP, 0 },
{ "tge", "s,t", MIPS_SPECIAL(0x30), MA_MIPS2, MO_RSD },
{ "tgeu", "s,t", MIPS_SPECIAL(0x31), MA_MIPS2, MO_RSD },
{ "tlt", "s,t", MIPS_SPECIAL(0x32), MA_MIPS2, MO_RSD },
{ "tltu", "s,t", MIPS_SPECIAL(0x33), MA_MIPS2, MO_RSD },
{ "teq", "s,t", MIPS_SPECIAL(0x34), MA_MIPS2, MO_RSD },
{ "tne", "s,t", MIPS_SPECIAL(0x36), MA_MIPS2, MO_RSD },
{ "dsll", "d,t,a", MIPS_SPECIAL(0x38), MA_MIPS3, MO_64BIT },
{ "dsll", "d,a", MIPS_SPECIAL(0x38), MA_MIPS3, MO_64BIT|MO_RDT },
{ "dsrl", "d,t,a", MIPS_SPECIAL(0x3A), MA_MIPS3, MO_64BIT },
{ "dsrl", "d,a", MIPS_SPECIAL(0x3A), MA_MIPS3, MO_64BIT|MO_RDT },
{ "dsra", "d,t,a", MIPS_SPECIAL(0x3B), MA_MIPS3, MO_64BIT },
{ "dsra", "d,a", MIPS_SPECIAL(0x3B), MA_MIPS3, MO_64BIT|MO_RDT },
{ "dsll32", "d,t,a", MIPS_SPECIAL(0x3C), MA_MIPS3, MO_64BIT },
{ "dsll32", "d,a", MIPS_SPECIAL(0x3C), MA_MIPS3, MO_64BIT|MO_RDT },
{ "dsrl32", "d,t,a", MIPS_SPECIAL(0x3E), MA_MIPS3, MO_64BIT },
{ "dsrl32", "d,a", MIPS_SPECIAL(0x3E), MA_MIPS3, MO_64BIT|MO_RDT },
{ "dsra32", "d,t,a", MIPS_SPECIAL(0x3F), MA_MIPS3, MO_64BIT },
{ "dsra32", "d,a", MIPS_SPECIAL(0x3F), MA_MIPS3, MO_64BIT|MO_RDT },
// REGIMM: encoded by the rt field when opcode field = REGIMM.
// 31---------26----------20-------16------------------------------0
// |= REGIMM| | rt | |
// ------6---------------------5------------------------------------
// |--000--|--001--|--010--|--011--|--100--|--101--|--110--|--111--| lo
// 00 | BLTZ | BGEZ | BLTZL | BGEZL | --- | --- | --- | --- | 00-07
// 01 | tgei | tgeiu | tlti | tltiu | teqi | --- | tnei | --- | 08-0F
// 10 | BLTZAL| BGEZAL|BLTZALL|BGEZALL| --- | --- | --- | --- | 10-17
// 11 | mtsab | mtsah | --- | --- | --- | --- | --- | --- | 18-1F
// hi |-------|-------|-------|-------|-------|-------|-------|-------|
{ "bltz", "s,i", MIPS_REGIMM(0x00), MA_MIPS1, MO_IPCR|MO_DELAY|MO_NODELAYSLOT },
{ "bgez", "s,i", MIPS_REGIMM(0x01), MA_MIPS1, MO_IPCR|MO_DELAY|MO_NODELAYSLOT },
{ "bltzl", "s,i", MIPS_REGIMM(0x02), MA_MIPS2, MO_IPCR|MO_DELAY|MO_NODELAYSLOT },
{ "bgezl", "s,i", MIPS_REGIMM(0x03), MA_MIPS2, MO_IPCR|MO_DELAY|MO_NODELAYSLOT },
{ "tgei", "s,i", MIPS_REGIMM(0x08), MA_MIPS2, 0 },
{ "tgeiu", "s,i", MIPS_REGIMM(0x09), MA_MIPS2, 0 },
{ "tlti", "s,i", MIPS_REGIMM(0x0A), MA_MIPS2, 0 },
{ "tltiu", "s,i", MIPS_REGIMM(0x0B), MA_MIPS2, 0 },
{ "teqi", "s,i", MIPS_REGIMM(0x0C), MA_MIPS2, 0 },
{ "tnei", "s,i", MIPS_REGIMM(0x0E), MA_MIPS2, 0 },
{ "bltzal", "s,i", MIPS_REGIMM(0x10), MA_MIPS1, MO_IPCR|MO_DELAY|MO_NODELAYSLOT },
{ "bgezal", "s,i", MIPS_REGIMM(0x11), MA_MIPS1, MO_IPCR|MO_DELAY|MO_NODELAYSLOT },
{ "bltzall","s,i", MIPS_REGIMM(0x12), MA_MIPS2, MO_IPCR|MO_DELAY|MO_NODELAYSLOT },
{ "bgezall","s,i", MIPS_REGIMM(0x13), MA_MIPS2, MO_IPCR|MO_DELAY|MO_NODELAYSLOT },
{ "mtsab", "s,i", MIPS_REGIMM(0x18), MA_PS2, 0 },
{ "mtsah", "s,i", MIPS_REGIMM(0x19), MA_PS2, 0 },
// 31-------26------21---------------------------------------------0
// |= COP1| rs | |
// -----6-------5---------------------------------------------------
// |--000--|--001--|--010--|--011--|--100--|--101--|--110--|--111--| lo
// 00 | MFC1 | --- | CFC1 | --- | MTC1 | --- | CTC1 | --- | 00..07
// 01 | BC* | --- | --- | --- | --- | --- | --- | --- | 08..0F
// 10 | S* | --- | --- | --- | W* | --- | --- | --- | 10..17
// 11 | --- | --- | --- | --- | --- | --- | --- | --- | 18..1F
// hi |-------|-------|-------|-------|-------|-------|-------|-------|
{ "mfc1", "t,S", MIPS_COP1(0x00), MA_MIPS2, 0 },
{ "cfc1", "t,S", MIPS_COP1(0x02), MA_MIPS2, 0 },
{ "mtc1", "t,S", MIPS_COP1(0x04), MA_MIPS2, 0 },
{ "ctc1", "t,S", MIPS_COP1(0x06), MA_MIPS2, 0 },
// 31---------21-------16------------------------------------------0
// |= COP1BC| rt | |
// ------11---------5-----------------------------------------------
// |--000--|--001--|--010--|--011--|--100--|--101--|--110--|--111--| lo
// 00 | BC1F | BC1T | BC1FL | BC1TL | --- | --- | --- | --- | 00..07
// 01 | --- | --- | --- | --- | --- | --- | --- | --- | 08..0F
// 10 | --- | --- | --- | --- | --- | --- | --- | --- | 10..17
// 11 | --- | --- | --- | --- | --- | --- | --- | --- | 18..1F
// hi |-------|-------|-------|-------|-------|-------|-------|-------|
{ "bc1f", "I", MIPS_COP1BC(0x00), MA_MIPS2, MO_IPCR|MO_DELAY|MO_NODELAYSLOT },
{ "bc1t", "I", MIPS_COP1BC(0x01), MA_MIPS2, MO_IPCR|MO_DELAY|MO_NODELAYSLOT },
{ "bc1fl", "I", MIPS_COP1BC(0x02), MA_MIPS2, MO_IPCR|MO_DELAY|MO_NODELAYSLOT },
{ "bc1tl", "I", MIPS_COP1BC(0x03), MA_MIPS2, MO_IPCR|MO_DELAY|MO_NODELAYSLOT },
// 31---------21------------------------------------------5--------0
// |= COP1S | | function|
// -----11----------------------------------------------------6-----
// |--000--|--001--|--010--|--011--|--100--|--101--|--110--|--111--| lo
// 000 | add | sub | mul | div | sqrt | abs | mov | neg | 00..07
// 001 | --- | --- | --- | --- |round.w|trunc.w|ceil.w |floor.w| 08..0F
// 010 | --- | --- | --- | --- | --- | --- | rsqrt | --- | 10..17
// 011 | adda | suba | mula | --- | madd | msub | madda | msuba | 18..1F
// 100 | --- | --- | --- | --- | cvt.w | --- | --- | --- | 20..27
// 101 | max | min | --- | --- | --- | --- | --- | --- | 28..2F
// 110 | c.f | c.un | c.eq | c.ueq |c.(o)lt| c.ult |c.(o)le| c.ule | 30..37
// 110 | c.sf | c.ngle| c.seq | c.ngl | c.lt | c.nge | c.le | c.ngt | 38..3F
// hi |-------|-------|-------|-------|-------|-------|-------|-------|
{ "add.s", "D,S,T", MIPS_COP1S(0x00), MA_MIPS2, 0 },
{ "add.s", "S,T", MIPS_COP1S(0x00), MA_MIPS2, MO_FRSD },
{ "sub.s", "D,S,T", MIPS_COP1S(0x01), MA_MIPS2, 0 },
{ "sub.s", "S,T", MIPS_COP1S(0x01), MA_MIPS2, MO_FRSD },
{ "mul.s", "D,S,T", MIPS_COP1S(0x02), MA_MIPS2, 0 },
{ "mul.s", "S,T", MIPS_COP1S(0x02), MA_MIPS2, MO_FRSD },
{ "div.s", "D,S,T", MIPS_COP1S(0x03), MA_MIPS2, 0 },
{ "div.s", "S,T", MIPS_COP1S(0x03), MA_MIPS2, MO_FRSD },
{ "sqrt.s", "D,S", MIPS_COP1S(0x04), MA_MIPS2, 0 },
{ "abs.s", "D,S", MIPS_COP1S(0x05), MA_MIPS2, 0 },
{ "mov.s", "D,S", MIPS_COP1S(0x06), MA_MIPS2, 0 },
{ "neg.s", "D,S", MIPS_COP1S(0x07), MA_MIPS2, 0 },
{ "round.w.s", "D,S", MIPS_COP1S(0x0C), MA_PSP, 0 },
{ "trunc.w.s", "D,S", MIPS_COP1S(0x0D), MA_PSP, 0 },
{ "ceil.w.s", "D,S", MIPS_COP1S(0x0E), MA_PSP, 0 },
{ "floor.w.s", "D,S", MIPS_COP1S(0x0F), MA_PSP, 0 },
{ "rsqrt.w.s", "D,S", MIPS_COP1S(0x16), MA_PS2, 0 },
{ "adda.s", "S,T", MIPS_COP1S(0x18), MA_PS2, 0 },
{ "suba.s", "S,T", MIPS_COP1S(0x19), MA_PS2, 0 },
{ "mula.s", "S,T", MIPS_COP1S(0x1A), MA_PS2, 0 },
{ "madd.s", "D,S,T", MIPS_COP1S(0x1C), MA_PS2, 0 },
{ "madd.s", "S,T", MIPS_COP1S(0x1C), MA_PS2, MO_FRSD },
{ "msub.s", "D,S,T", MIPS_COP1S(0x1D), MA_PS2, 0 },
{ "msub.s", "S,T", MIPS_COP1S(0x1D), MA_PS2, MO_FRSD },
{ "madda.s", "S,T", MIPS_COP1S(0x1E), MA_PS2, 0 },
{ "msuba.s", "S,T", MIPS_COP1S(0x1F), MA_PS2, 0 },
{ "cvt.w.s", "D,S", MIPS_COP1S(0x24), MA_MIPS2, 0 },
{ "max.s", "D,S,T", MIPS_COP1S(0x28), MA_PS2, 0 },
{ "min.s", "D,S,T", MIPS_COP1S(0x29), MA_PS2, 0 },
{ "c.f.s", "S,T", MIPS_COP1S(0x30), MA_MIPS2, 0 },
{ "c.un.s", "S,T", MIPS_COP1S(0x31), MA_PSP, 0 },
{ "c.eq.s", "S,T", MIPS_COP1S(0x32), MA_MIPS2, 0 },
{ "c.ueq.s", "S,T", MIPS_COP1S(0x33), MA_PSP, 0 },
{ "c.olt.s", "S,T", MIPS_COP1S(0x34), MA_PSP, 0 },
{ "c.lt.s", "S,T", MIPS_COP1S(0x34), MA_PS2, 0 },
{ "c.ult.s", "S,T", MIPS_COP1S(0x35), MA_PSP, 0 },
{ "c.ole.s", "S,T", MIPS_COP1S(0x36), MA_PSP, 0 },
{ "c.le.s", "S,T", MIPS_COP1S(0x36), MA_PS2, 0 },
{ "c.ule.s", "S,T", MIPS_COP1S(0x37), MA_PSP, 0 },
{ "c.sf.s", "S,T", MIPS_COP1S(0x38), MA_PSP, 0 },
{ "c.ngle.s", "S,T", MIPS_COP1S(0x39), MA_PSP, 0 },
{ "c.seq.s", "S,T", MIPS_COP1S(0x3A), MA_PSP, 0 },
{ "c.ngl.s", "S,T", MIPS_COP1S(0x3B), MA_PSP, 0 },
{ "c.lt.s", "S,T", MIPS_COP1S(0x3C), MA_PSP, 0 },
{ "c.nge.s", "S,T", MIPS_COP1S(0x3D), MA_PSP, 0 },
{ "c.le.s", "S,T", MIPS_COP1S(0x3E), MA_PSP, 0 },
{ "c.ngt.s", "S,T", MIPS_COP1S(0x3F), MA_PSP, 0 },
// COP1W: encoded by function field
// 31---------21------------------------------------------5--------0
// |= COP1W | | function|
// -----11----------------------------------------------------6-----
// |--000--|--001--|--010--|--011--|--100--|--101--|--110--|--111--| lo
// 000 | --- | --- | --- | --- | --- | --- | --- | --- | 00..07
// 001 | --- | --- | --- | --- | --- | --- | --- | --- | 08..0F
// 010 | --- | --- | --- | --- | --- | --- | --- | --- | 10..17
// 011 | --- | --- | --- | --- | --- | --- | --- | --- | 18..1F
// 100 |cvt.s.w| --- | --- | --- | --- | --- | --- | --- | 20..27
// 101 | --- | --- | --- | --- | --- | --- | --- | --- | 28..2F
// 110 | --- | --- | --- | --- | --- | --- | --- | --- | 30..37
// 110 | --- | --- | --- | --- | --- | --- | --- | --- | 38..3F
// hi |-------|-------|-------|-------|-------|-------|-------|-------|
{ "cvt.s.w", "D,S", MIPS_COP1W(0x20), MA_MIPS2, 0 },
// 31---------26-----23--------------------------------------------0
// |= VFPU0| VOP | |
// ------6--------3-------------------------------------------------
// |--000--|--001--|--010--|--011--|--100--|--101--|--110--|--111--|
// 000 | VADD | VSUB | VSBN | --- | --- | --- | --- | VDIV | 00..07
// hi |-------|-------|-------|-------|-------|-------|-------|-------|
{ "vadd.S", "vd,vs,vt", MIPS_VFPU0(0x00), MA_PSP, MO_VFPU },
{ "vsub.S", "vd,vs,vt", MIPS_VFPU0(0x01), MA_PSP, MO_VFPU },
{ "vsbn.S", "vd,vs,vt", MIPS_VFPU0(0x02), MA_PSP, MO_VFPU },
{ "vdiv.S", "vd,vs,vt", MIPS_VFPU0(0x07), MA_PSP, MO_VFPU },
// allegrex0
{ "seh", "d,t", MIPS_ALLEGREX0(16), MA_PSP },
{ "seh", "d,t", MIPS_ALLEGREX0(24), MA_PSP },
// END
{ NULL, NULL, 0, 0 }
};
const MipsArchDefinition mipsArchs[] = {
// MARCH_PSX
{ "PSX", MA_MIPS1, MA_EXPSX, 0 },
// MARCH_N64
{ "N64", MA_MIPS1|MA_MIPS2|MA_MIPS3, MA_EXN64, MO_FPU },
// MARCH_PS2
{ "PS2", MA_MIPS1|MA_MIPS2|MA_MIPS3|MA_PS2, MA_EXPS2, MO_64BIT|MO_FPU },
// MARCH_PSP
{ "PSP", MA_MIPS1|MA_MIPS2|MA_MIPS3|MA_PSP, MA_EXPSP, MO_FPU },
// MARCH_INVALID
{ "Invalid", 0, 0, 0 },
};

View File

@ -0,0 +1,78 @@
#pragma once
#define MA_MIPS1 0x0000001
#define MA_MIPS2 0x0000002
#define MA_MIPS3 0x0000004
#define MA_MIPS4 0x0000008
#define MA_PS2 0x0000010
#define MA_PSP 0x0000020
#define MA_EXPSX 0x0000100
#define MA_EXN64 0x0000200
#define MA_EXPS2 0x0000400
#define MA_EXPSP 0x0000800
#define MO_IPCA 0x00000001 // pc >> 2
#define MO_IPCR 0x00000002 // PC, -> difference >> 2
#define MO_RSD 0x00000004 // rs = rd
#define MO_RST 0x00000008 // rs = rt
#define MO_RDT 0x00000010 // rd = rt
#define MO_DELAY 0x00000020 // delay slot follows
#define MO_NODELAYSLOT 0x00000040 // can't be in a delay slot
#define MO_DELAYRT 0x00000080 // rt won't be available for one instruction
#define MO_IGNORERTD 0x00000100 // don't care for rt delay
#define MO_FRSD 0x00000200 // float rs + rd
#define MO_IMMALIGNED 0x00000400 // immediate 4 byte aligned
#define MO_VFPU_MIXED 0x00000800 // mixed mode vfpu register
#define MO_VFPU_6BIT 0x00001000 // vfpu register can have 6 bits max
#define MO_VFPU_SINGLE 0x00002000 // single vfpu reg
#define MO_VFPU_QUAD 0x00004000 // quad vfpu reg
#define MO_VFPU 0x00008000 // vfpu type opcode
#define MO_64BIT 0x00010000 // only available on 64 bit cpus
#define MO_FPU 0x00020000 // only available with an fpu
#define BITFIELD(START,LENGTH,VALUE) (((VALUE) << (START)))
#define MIPS_FUNC(VALUE) BITFIELD(0,6,(VALUE))
#define MIPS_SA(VALUE) BITFIELD(6,5,(VALUE))
#define MIPS_SECFUNC(VALUE) MIPS_SA((VALUE))
#define MIPS_OP(VALUE) BITFIELD(26,6,(VALUE))
#define MIPS_RS(VALUE) BITFIELD(21,5,(VALUE))
#define MIPS_RT(VALUE) BITFIELD(16,5,(VALUE))
#define MIPS_RD(VALUE) BITFIELD(11,5,(VALUE))
#define MIPS_FS(VALUE) MIPS_RD((VALUE))
#define MIPS_FT(VALUE) MIPS_RT((VALUE))
#define MIPS_FD(VALUE) MIPS_SA((VALUE))
#define MIPS_SPECIAL(VALUE) (MIPS_OP(0) | MIPS_FUNC(VALUE))
#define MIPS_REGIMM(VALUE) (MIPS_OP(1) | MIPS_RT(VALUE))
#define MIPS_COP0(VALUE) (MIPS_OP(16) | MIPS_RS(VALUE))
#define MIPS_COP1(VALUE) (MIPS_OP(17) | MIPS_RS(VALUE))
#define MIPS_COP1BC(VALUE) (MIPS_COP1(8) | MIPS_RT(VALUE))
#define MIPS_COP1S(VALUE) (MIPS_COP1(16) | MIPS_FUNC(VALUE))
#define MIPS_COP1W(VALUE) (MIPS_COP1(20) | MIPS_FUNC(VALUE))
#define MIPS_VFPUSIZE(VALUE) ( (((VALUE) & 1) << 7) | (((VALUE) & 2) << 14) )
#define MIPS_VFPU0(VALUE) (MIPS_OP(0x18) | BITFIELD(23,3,(VALUE)))
#define MIPS_ALLEGREX0(VALUE) (MIPS_SPECIAL(32) | MIPS_SECFUNC(VALUE))
struct MipsArchDefinition
{
const char* name;
int supportSets;
int excludeMask;
int flags;
};
extern const MipsArchDefinition mipsArchs[];
typedef struct {
const char* name;
const char* encoding;
int destencoding;
int archs;
int flags;
} tMipsOpcode;
extern const tMipsOpcode MipsOpcodes[];

View File

@ -428,6 +428,8 @@
<ClCompile Include="..\..\DebugTools\DisassemblyManager.cpp" /> <ClCompile Include="..\..\DebugTools\DisassemblyManager.cpp" />
<ClCompile Include="..\..\DebugTools\ExpressionParser.cpp" /> <ClCompile Include="..\..\DebugTools\ExpressionParser.cpp" />
<ClCompile Include="..\..\DebugTools\MIPSAnalyst.cpp" /> <ClCompile Include="..\..\DebugTools\MIPSAnalyst.cpp" />
<ClCompile Include="..\..\DebugTools\MipsAssembler.cpp" />
<ClCompile Include="..\..\DebugTools\MipsAssemblerTables.cpp" />
<ClCompile Include="..\..\DebugTools\SymbolMap.cpp" /> <ClCompile Include="..\..\DebugTools\SymbolMap.cpp" />
<ClCompile Include="..\..\GameDatabase.cpp" /> <ClCompile Include="..\..\GameDatabase.cpp" />
<ClCompile Include="..\..\Gif_Logger.cpp" /> <ClCompile Include="..\..\Gif_Logger.cpp" />
@ -715,6 +717,8 @@
<ClInclude Include="..\..\DebugTools\DisassemblyManager.h" /> <ClInclude Include="..\..\DebugTools\DisassemblyManager.h" />
<ClInclude Include="..\..\DebugTools\ExpressionParser.h" /> <ClInclude Include="..\..\DebugTools\ExpressionParser.h" />
<ClInclude Include="..\..\DebugTools\MIPSAnalyst.h" /> <ClInclude Include="..\..\DebugTools\MIPSAnalyst.h" />
<ClInclude Include="..\..\DebugTools\MipsAssembler.h" />
<ClInclude Include="..\..\DebugTools\MipsAssemblerTables.h" />
<ClInclude Include="..\..\DebugTools\SymbolMap.h" /> <ClInclude Include="..\..\DebugTools\SymbolMap.h" />
<ClInclude Include="..\..\GameDatabase.h" /> <ClInclude Include="..\..\GameDatabase.h" />
<ClInclude Include="..\..\Gif_Unit.h" /> <ClInclude Include="..\..\Gif_Unit.h" />

View File

@ -826,6 +826,12 @@
<ClCompile Include="..\..\DebugTools\MIPSAnalyst.cpp"> <ClCompile Include="..\..\DebugTools\MIPSAnalyst.cpp">
<Filter>System\Ps2\Debug</Filter> <Filter>System\Ps2\Debug</Filter>
</ClCompile> </ClCompile>
<ClCompile Include="..\..\DebugTools\MipsAssembler.cpp">
<Filter>System\Ps2\Debug</Filter>
</ClCompile>
<ClCompile Include="..\..\DebugTools\MipsAssemblerTables.cpp">
<Filter>System\Ps2\Debug</Filter>
</ClCompile>
<ClCompile Include="..\..\DebugTools\SymbolMap.cpp"> <ClCompile Include="..\..\DebugTools\SymbolMap.cpp">
<Filter>System\Ps2\Debug</Filter> <Filter>System\Ps2\Debug</Filter>
</ClCompile> </ClCompile>
@ -1243,6 +1249,12 @@
<ClInclude Include="..\..\DebugTools\MIPSAnalyst.h"> <ClInclude Include="..\..\DebugTools\MIPSAnalyst.h">
<Filter>System\Ps2\Debug</Filter> <Filter>System\Ps2\Debug</Filter>
</ClInclude> </ClInclude>
<ClInclude Include="..\..\DebugTools\MipsAssembler.h">
<Filter>System\Ps2\Debug</Filter>
</ClInclude>
<ClInclude Include="..\..\DebugTools\MipsAssemblerTables.h">
<Filter>System\Ps2\Debug</Filter>
</ClInclude>
<ClInclude Include="..\..\DebugTools\SymbolMap.h"> <ClInclude Include="..\..\DebugTools\SymbolMap.h">
<Filter>System\Ps2\Debug</Filter> <Filter>System\Ps2\Debug</Filter>
</ClInclude> </ClInclude>

View File

@ -413,6 +413,8 @@
<ClCompile Include="..\..\DebugTools\DisassemblyManager.cpp" /> <ClCompile Include="..\..\DebugTools\DisassemblyManager.cpp" />
<ClCompile Include="..\..\DebugTools\ExpressionParser.cpp" /> <ClCompile Include="..\..\DebugTools\ExpressionParser.cpp" />
<ClCompile Include="..\..\DebugTools\MIPSAnalyst.cpp" /> <ClCompile Include="..\..\DebugTools\MIPSAnalyst.cpp" />
<ClCompile Include="..\..\DebugTools\MipsAssembler.cpp" />
<ClCompile Include="..\..\DebugTools\MipsAssemblerTables.cpp" />
<ClCompile Include="..\..\DebugTools\SymbolMap.cpp" /> <ClCompile Include="..\..\DebugTools\SymbolMap.cpp" />
<ClCompile Include="..\..\GameDatabase.cpp" /> <ClCompile Include="..\..\GameDatabase.cpp" />
<ClCompile Include="..\..\Gif_Logger.cpp" /> <ClCompile Include="..\..\Gif_Logger.cpp" />
@ -701,6 +703,8 @@
<ClInclude Include="..\..\DebugTools\DisassemblyManager.h" /> <ClInclude Include="..\..\DebugTools\DisassemblyManager.h" />
<ClInclude Include="..\..\DebugTools\ExpressionParser.h" /> <ClInclude Include="..\..\DebugTools\ExpressionParser.h" />
<ClInclude Include="..\..\DebugTools\MIPSAnalyst.h" /> <ClInclude Include="..\..\DebugTools\MIPSAnalyst.h" />
<ClInclude Include="..\..\DebugTools\MipsAssembler.h" />
<ClInclude Include="..\..\DebugTools\MipsAssemblerTables.h" />
<ClInclude Include="..\..\DebugTools\SymbolMap.h" /> <ClInclude Include="..\..\DebugTools\SymbolMap.h" />
<ClInclude Include="..\..\GameDatabase.h" /> <ClInclude Include="..\..\GameDatabase.h" />
<ClInclude Include="..\..\Gif_Unit.h" /> <ClInclude Include="..\..\Gif_Unit.h" />

View File

@ -841,6 +841,12 @@
<ClCompile Include="..\..\DebugTools\MIPSAnalyst.cpp"> <ClCompile Include="..\..\DebugTools\MIPSAnalyst.cpp">
<Filter>System\Ps2\Debug</Filter> <Filter>System\Ps2\Debug</Filter>
</ClCompile> </ClCompile>
<ClCompile Include="..\..\DebugTools\MipsAssembler.cpp">
<Filter>System\Ps2\Debug</Filter>
</ClCompile>
<ClCompile Include="..\..\DebugTools\MipsAssemblerTables.cpp">
<Filter>System\Ps2\Debug</Filter>
</ClCompile>
<ClCompile Include="..\..\DebugTools\SymbolMap.cpp"> <ClCompile Include="..\..\DebugTools\SymbolMap.cpp">
<Filter>System\Ps2\Debug</Filter> <Filter>System\Ps2\Debug</Filter>
</ClCompile> </ClCompile>
@ -1258,6 +1264,12 @@
<ClInclude Include="..\..\DebugTools\MIPSAnalyst.h"> <ClInclude Include="..\..\DebugTools\MIPSAnalyst.h">
<Filter>System\Ps2\Debug</Filter> <Filter>System\Ps2\Debug</Filter>
</ClInclude> </ClInclude>
<ClInclude Include="..\..\DebugTools\MipsAssembler.h">
<Filter>System\Ps2\Debug</Filter>
</ClInclude>
<ClInclude Include="..\..\DebugTools\MipsAssemblerTables.h">
<Filter>System\Ps2\Debug</Filter>
</ClInclude>
<ClInclude Include="..\..\DebugTools\SymbolMap.h"> <ClInclude Include="..\..\DebugTools\SymbolMap.h">
<Filter>System\Ps2\Debug</Filter> <Filter>System\Ps2\Debug</Filter>
</ClInclude> </ClInclude>

View File

@ -413,6 +413,8 @@
<ClCompile Include="..\..\DebugTools\DisassemblyManager.cpp" /> <ClCompile Include="..\..\DebugTools\DisassemblyManager.cpp" />
<ClCompile Include="..\..\DebugTools\ExpressionParser.cpp" /> <ClCompile Include="..\..\DebugTools\ExpressionParser.cpp" />
<ClCompile Include="..\..\DebugTools\MIPSAnalyst.cpp" /> <ClCompile Include="..\..\DebugTools\MIPSAnalyst.cpp" />
<ClCompile Include="..\..\DebugTools\MipsAssembler.cpp" />
<ClCompile Include="..\..\DebugTools\MipsAssemblerTables.cpp" />
<ClCompile Include="..\..\DebugTools\SymbolMap.cpp" /> <ClCompile Include="..\..\DebugTools\SymbolMap.cpp" />
<ClCompile Include="..\..\GameDatabase.cpp" /> <ClCompile Include="..\..\GameDatabase.cpp" />
<ClCompile Include="..\..\Gif_Logger.cpp" /> <ClCompile Include="..\..\Gif_Logger.cpp" />
@ -701,6 +703,8 @@
<ClInclude Include="..\..\DebugTools\DisassemblyManager.h" /> <ClInclude Include="..\..\DebugTools\DisassemblyManager.h" />
<ClInclude Include="..\..\DebugTools\ExpressionParser.h" /> <ClInclude Include="..\..\DebugTools\ExpressionParser.h" />
<ClInclude Include="..\..\DebugTools\MIPSAnalyst.h" /> <ClInclude Include="..\..\DebugTools\MIPSAnalyst.h" />
<ClInclude Include="..\..\DebugTools\MipsAssembler.h" />
<ClInclude Include="..\..\DebugTools\MipsAssemblerTables.h" />
<ClInclude Include="..\..\DebugTools\SymbolMap.h" /> <ClInclude Include="..\..\DebugTools\SymbolMap.h" />
<ClInclude Include="..\..\GameDatabase.h" /> <ClInclude Include="..\..\GameDatabase.h" />
<ClInclude Include="..\..\Gif_Unit.h" /> <ClInclude Include="..\..\Gif_Unit.h" />

View File

@ -856,6 +856,12 @@
<ClCompile Include="..\..\CDVD\CompressedFileReader.cpp"> <ClCompile Include="..\..\CDVD\CompressedFileReader.cpp">
<Filter>System\ISO</Filter> <Filter>System\ISO</Filter>
</ClCompile> </ClCompile>
<ClCompile Include="..\..\DebugTools\MipsAssemblerTables.cpp">
<Filter>System\Ps2\Debug</Filter>
</ClCompile>
<ClCompile Include="..\..\DebugTools\MipsAssembler.cpp">
<Filter>System\Ps2\Debug</Filter>
</ClCompile>
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<ClInclude Include="..\..\Patch.h"> <ClInclude Include="..\..\Patch.h">
@ -1270,6 +1276,12 @@
<ClInclude Include="..\..\CDVD\zlib_indexed.h"> <ClInclude Include="..\..\CDVD\zlib_indexed.h">
<Filter>System\ISO</Filter> <Filter>System\ISO</Filter>
</ClInclude> </ClInclude>
<ClInclude Include="..\..\DebugTools\MipsAssemblerTables.h">
<Filter>System\Ps2\Debug</Filter>
</ClInclude>
<ClInclude Include="..\..\DebugTools\MipsAssembler.h">
<Filter>System\Ps2\Debug</Filter>
</ClInclude>
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<ResourceCompile Include="..\..\..\3rdparty\wxWidgets\include\wx\msw\wx.rc"> <ResourceCompile Include="..\..\..\3rdparty\wxWidgets\include\wx\msw\wx.rc">