bool MipsCheckImmediate(const char* Source, char* Dest, int& RetLen) { int BufferPos = 0; int l; if (MipsGetRegister(Source,l) != -1) // there's a register -> no immediate { return false; } int SourceLen = 0; while (true) { if (*Source == '\'' && *(Source+2) == '\'') { Dest[BufferPos++] = *Source++; Dest[BufferPos++] = *Source++; Dest[BufferPos++] = *Source++; SourceLen+=3; continue; } if (*Source == 0 || *Source == '\n' || *Source == ',') { Dest[BufferPos] = 0; break; } if ( *Source == ' ' || *Source == '\t') { Source++; SourceLen++; continue; } if (*Source == '(') // could also be part of the opcode, ie (r4) { if (MipsGetRegister(Source+1,l) != -1) // stop if it is { Dest[BufferPos] = 0; break; } } Dest[BufferPos++] = *Source++; SourceLen++; } if (BufferPos == 0) return false; RetLen = SourceLen; return true; }
bool CMipsInstruction::LoadEncoding(const tMipsOpcode& SourceOpcode, char* Line) { int RetLen; CStringList List; 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; } char* SourceEncoding = SourceOpcode.encoding; char* OriginalLine = Line; while (*Line == ' ' || *Line == '\t') Line++; if (!(*SourceEncoding == 0 && *Line == 0)) { while (*SourceEncoding != NULL) { 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': // vfpu vector register switch (*(SourceEncoding+1)) { case 's': if (MipsGetVFPURegister(Line,registers.vrs,vfpuSize) == false) return false; if (registers.vrs.type != MIPSVFPU_VECTOR) return false; if ((SourceOpcode.flags & MO_VFPU_6BIT) && (registers.vrs.num & 0x40)) return false; break; case 't': if (MipsGetVFPURegister(Line,registers.vrt,vfpuSize) == false) return false; if (registers.vrt.type != MIPSVFPU_VECTOR) return false; if ((SourceOpcode.flags & MO_VFPU_6BIT) && (registers.vrt.num & 0x40)) return false; break; case 'd': if (MipsGetVFPURegister(Line,registers.vrd,vfpuSize) == false) return false; if (registers.vrd.type != MIPSVFPU_VECTOR) return false; if ((SourceOpcode.flags & MO_VFPU_6BIT) && (registers.vrd.num & 0x40)) return false; break; default: return false; } Line += 4; SourceEncoding += 2; break; case 'a': // 5 bit immediate if (MipsCheckImmediate(Line,immediate.expression,RetLen) == false) return false; immediateType = MIPS_IMMEDIATE5; Line += RetLen; SourceEncoding++; break; case 'i': // 16 bit immediate if (MipsCheckImmediate(Line,immediate.expression,RetLen) == false) return false; immediateType = MIPS_IMMEDIATE16; Line += RetLen; SourceEncoding++; break; case 'b': // 20 bit immediate if (MipsCheckImmediate(Line,immediate.expression,RetLen) == false) return false; immediateType = MIPS_IMMEDIATE20; Line += RetLen; SourceEncoding++; break; case 'I': // 32 bit immediate if (MipsCheckImmediate(Line,immediate.expression,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; if (immediate.expression.isLoaded()) { if (immediate.expression.check() == false) { NoCheckError = true; return false; } } setOmittedRegisters(); return true; }
bool CMipsInstruction::LoadEncoding(const tMipsOpcode& SourceOpcode, char* Line) { char ImmediateBuffer[512]; int RetLen; bool Immediate = false; const char *SourceEncoding = SourceOpcode.encoding; 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 ((Vars.rt = MipsGetFloatRegister(Line,RetLen)) == -1) return false; Line += RetLen; SourceEncoding++; break; case 'D': // float reg if ((Vars.rd = MipsGetFloatRegister(Line,RetLen)) == -1) return false; Line += RetLen; SourceEncoding++; break; case 'S': // float reg if ((Vars.rs = MipsGetFloatRegister(Line,RetLen)) == -1) return false; Line += RetLen; SourceEncoding++; break; case 't': if ((Vars.rt = MipsGetRegister(Line,RetLen)) == -1) return false; Line += RetLen; SourceEncoding++; break; case 'd': if ((Vars.rd = MipsGetRegister(Line,RetLen)) == -1) return false; Line += RetLen; SourceEncoding++; break; case 's': if ((Vars.rs = MipsGetRegister(Line,RetLen)) == -1) return false; Line += RetLen; SourceEncoding++; break; case 'i': // 16 bit immediate case 'I': // 32 bit immediate case 'a': // 5 bit immediate case 'b': // 20 bit immediate if (MipsCheckImmediate(Line,ImmediateBuffer,RetLen) == false) return false; Immediate = true; Line += RetLen; SourceEncoding++; break; case 'r': // forced register if (MipsGetRegister(Line,RetLen) != *(SourceEncoding+1)) return false; Line += RetLen; SourceEncoding += 2; break; default: // everything else if (*SourceEncoding++ != *Line++) return false; break; } } } while (*Line == ' ' || *Line == '\t') Line++; if (*Line != 0) return false; // there's something else at the end, bad // the opcode is fine - now set all remaining flags Opcode = SourceOpcode; if (Immediate == true) { u32 imm; PostfixExpression postfix; if (cpu->initExpression(ImmediateBuffer,postfix) == false) return false; if (cpu->parseExpression(postfix,imm) == false) return false; Vars.Immediate = (int) imm; if (Opcode.flags & O_I5) { Vars.ImmediateType = MIPS_IMMEDIATE5; } else if (Opcode.flags & O_I16) { Vars.ImmediateType = MIPS_IMMEDIATE16; } else if (Opcode.flags & O_I20) { Vars.ImmediateType = MIPS_IMMEDIATE20; } else if (Opcode.flags & O_I26) { Vars.ImmediateType = MIPS_IMMEDIATE26; } } else { Vars.ImmediateType = MIPS_NOIMMEDIATE; } return true; }
bool CMipsInstruction::LoadEncoding(const tMipsOpcode& SourceOpcode, const char* Line) { int RetLen; CStringList List; bool Immediate = false; immediateType = MipsImmediateType::None; if (!hasFixedSecondaryImmediate) secondaryImmediateType = MipsSecondaryImmediateType::None; registers.reset(); vectorCondition = -1; 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': // psp vfpu vector register switch (*(SourceEncoding+1)) { case 's': if (parseVFPURegister(Line,registers.vrs,vfpuSize) == false) return false; if (registers.vrs.type != MIPSVFPU_VECTOR) return false; if ((SourceOpcode.flags & MO_VFPU_6BIT) && (registers.vrs.num & 0x40)) return false; Line += 4; break; case 't': if (parseVFPURegister(Line,registers.vrt,vfpuSize) == false) return false; if (registers.vrt.type != MIPSVFPU_VECTOR) return false; if ((SourceOpcode.flags & MO_VFPU_6BIT) && (registers.vrt.num & 0x40)) return false; Line += 4; break; case 'd': if (parseVFPURegister(Line,registers.vrd,vfpuSize) == false) return false; if (registers.vrd.type != MIPSVFPU_VECTOR) return false; if ((SourceOpcode.flags & MO_VFPU_6BIT) && (registers.vrd.num & 0x40)) return false; Line += 4; break; case 'c': if (parseVfpuControlRegister(Line,registers.vrd,RetLen) == false) return false; Line += RetLen; break; default: return false; } SourceEncoding += 2; 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 'i': // standard immediate if (MipsCheckImmediate(Line,immediate.expression,RetLen) == false) return false; Line += RetLen; SourceEncoding++; if (*SourceEncoding == 'h') // half float { SourceEncoding++; immediateType = MipsImmediateType::ImmediateHalfFloat; } else { int num = 0; while (*SourceEncoding >= '0' && *SourceEncoding <= '9') { num = num*10 + *SourceEncoding-'0'; SourceEncoding++; } switch (num) { case 5: immediateType = MipsImmediateType::Immediate5; break; case 7: immediateType = MipsImmediateType::Immediate7; break; case 8: immediateType = MipsImmediateType::Immediate8; break; case 16: immediateType = MipsImmediateType::Immediate16; break; case 20: immediateType = MipsImmediateType::Immediate20; break; case 26: immediateType = MipsImmediateType::Immediate26; break; default: return false; } } break; case 'j': switch (*(SourceEncoding+1)) { case 'e': if (MipsCheckImmediate(Line,secondaryImmediate.expression,RetLen) == false) return false; secondaryImmediateType = MipsSecondaryImmediateType::Ext; break; case 'i': if (MipsCheckImmediate(Line,secondaryImmediate.expression,RetLen) == false) return false; secondaryImmediateType = MipsSecondaryImmediateType::Ins; break; case 'b': if (parseCop2BranchCondition(Line,secondaryImmediate.originalValue,RetLen) == false) return false; secondaryImmediateType = MipsSecondaryImmediateType::Cop2BranchType; secondaryImmediate.value = secondaryImmediate.originalValue; break; } Line += RetLen; SourceEncoding += 2; break; case 'r': // forced register if (MipsGetRegister(Line,RetLen) != *(SourceEncoding+1)) return false; Line += RetLen; SourceEncoding += 2; break; case 'C': if ((vectorCondition = parseVFPUCondition(Line, RetLen)) == -1) return false; Line += RetLen; SourceEncoding++; break; case 'W': // vfpu argument switch (*(SourceEncoding+1)) { case 's': if (parseVpfxsParameter(Line,immediate.originalValue,RetLen) == false) return false; immediateType = MipsImmediateType::Immediate20_0; break; case 'd': if (parseVpfxdParameter(Line,immediate.originalValue,RetLen) == false) return false; immediateType = MipsImmediateType::Immediate16; break; case 'c': if (parseVcstParameter(Line,immediate.originalValue,RetLen) == false) return false; immediateType = MipsImmediateType::Immediate5; break; default: return false; } immediate.value = immediate.originalValue; 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; if (immediate.expression.isLoaded()) { if (immediate.expression.check() == false) { NoCheckError = true; return false; } } if (secondaryImmediate.expression.isLoaded()) { if (secondaryImmediate.expression.check() == false) { NoCheckError = true; return false; } } setOmittedRegisters(); 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; }
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; }