Пример #1
0
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;
}
Пример #2
0
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;
}
Пример #3
0
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;
}
Пример #4
0
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;
}
Пример #5
0
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;
}
Пример #6
0
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;
}