示例#1
0
bool CThumbInstruction::LoadEncoding(const tThumbOpcode& SourceOpcode, char* Line)
{
	char ImmediateBuffer[512];

	int p,RetLen;
	CStringList List;
	bool Immediate = false;

	char* SourceEncoding = SourceOpcode.mask;
	char* OriginalLine = Line;

	while (*Line == ' ' || *Line == '\t') Line++;
	tArmRegisterInfo* Info;

	if (!(*SourceEncoding == 0 && *Line == 0))
	{
		while (*SourceEncoding != NULL)
		{
			while (*Line == ' ' || *Line == '\t') Line++;
//			if (*Line == 0) return false;

			switch (*SourceEncoding)
			{
			case 'd': case 's': case 'n': case 'o':
			case 'D': case 'S':	// registers
				for (int i = 0; ; i++)
				{
					if (RegisterLookup[i].Character == *SourceEncoding)
					{
						Info = (tArmRegisterInfo*)((int) (&Vars) + RegisterLookup[i].StructOffset);
						if (ArmGetRegister(Line,RetLen,*Info) == false) return false;
						if (Info->Number > RegisterLookup[i].MaxNum) return false;
						Line += RetLen;
						SourceEncoding++;
						break;
					}
				}
				break;
/*			case 'd':	// low reg
				if (ArmGetRegister(Line,RetLen,Vars.rd) == false) return false;
				if (Vars.rd.Number > 7) return false;
				Line += RetLen;
				SourceEncoding++;
				break;
			case 's':	// low reg
				if (ArmGetRegister(Line,RetLen,Vars.rs) == false) return false;
				if (Vars.rs.Number > 7) return false;
				Line += RetLen;
				SourceEncoding++;
				break;
			case 'n':	// low reg
				if (ArmGetRegister(Line,RetLen,Vars.rn) == false) return false;
				if (Vars.rn.Number > 7) return false;
				Line += RetLen;
				SourceEncoding++;
				break;
			case 'o':	// low reg
				if (ArmGetRegister(Line,RetLen,Vars.ro) == false) return false;
				if (Vars.ro.Number > 7) return false;
				Line += RetLen;
				SourceEncoding++;
				break;
			case 'D':	// high reg
				if (ArmGetRegister(Line,RetLen,Vars.rd) == false) return false;
				Line += RetLen;
				SourceEncoding++;
				break;
			case 'S':	// high reg
				if (ArmGetRegister(Line,RetLen,Vars.rs) == false) return false;
				Line += RetLen;
				SourceEncoding++;
				break;*/
			case 'I':	// immediate
			case 'i':
				if (ArmCheckImmediate(Line,ImmediateBuffer,RetLen,List) == false) return false;
				Vars.ImmediateBitLen = *(SourceEncoding+1);
				Line += RetLen;
				SourceEncoding += 2;
				break;
			case 'r':	// forced register
				if (ArmGetRegister(Line,RetLen) != *(SourceEncoding+1)) return false;
				Line += RetLen;
				SourceEncoding += 2;
				break;
			case 'R':	// rlist
				memcpy(&p,&SourceEncoding[1],2);
				if (ArmGetRlist(Line,RetLen,p,Vars.rlist) == false) return false;
				memcpy(Vars.RlistStr,Line,RetLen);
				Vars.RlistStr[RetLen] = 0;
				Line += RetLen;
				SourceEncoding += 3;
				break;
			case '/':	// optional characters
				if (*Line == *(SourceEncoding+1)) Line++;
				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, bad

	// opcode is ok - now set all flags
	Opcode = SourceOpcode;

	if (Opcode.flags & THUMB_IMMEDIATE)
	{
		if (CheckPostfix(List,true) == false)
		{
			Logger::printError(Logger::Error,L"Invalid expression \"%S\"",ImmediateBuffer);
			NoCheckError = true;
			return false;
		}
		Vars.ImmediateExpression.Load(List);
	}

	OpcodeSize = Opcode.flags & THUMB_LONG ? 4 : 2;
	return true;
}
示例#2
0
/*
			case 'M':	// cop register m
				if (ArmGetCopRegister(Line,RetLen,Vars.CopData.cm) == false) return false;
				Line += RetLen;
				SourceEncoding++;*/
bool CArmInstruction::LoadEncoding(const tArmOpcode& SourceOpcode, char* Line)
{
	int RetLen;
	bool Immediate = false;

	Vars.psr= false;
	Vars.writeback = false;
	Vars.SignPlus = false;
	Vars.Opcode.UseNewEncoding = false;
	Vars.Opcode.UseNewType = false;
		
	char* SourceEncoding = (char*)(SourceOpcode.mask);
	char* OriginalLine = Line;

	while (*Line == ' ' || *Line == '\t') Line++;

	tArmRegisterInfo* Info;
	if (!(*SourceEncoding == 0 && *Line == 0))
	{
		while (*SourceEncoding != 0)
		{
			while (*Line == ' ' || *Line == '\t') Line++;
//			if (*Line == 0) return false;

			switch (*SourceEncoding)
			{
			case 'd': case 's': case 'n': case 'm':
			case 'D': case 'N': case 'M':	// all of them are registers
				for (int i = 0; ; i++)
				{
					if (RegisterLookup[i].Character == *SourceEncoding)
					{
						Info = (tArmRegisterInfo*)((uintptr_t) (&Vars) + RegisterLookup[i].StructOffset);
						if (RegisterLookup[i].type == ARMREG_NORMAL)
						{
							if (ArmGetRegister(Line,RetLen,*Info) == false) return false;
							if (*(SourceEncoding+1) == '1' && Info->Number == 15) return false;
							Line += RetLen;
							SourceEncoding += 2;
						} else {
							if (ArmGetCopRegister(Line,RetLen,*Info) == false) return false;
							Line += RetLen;
							SourceEncoding++;
						}
						break;
					}
				}
				break;
/*			case 'd':	// reg
				if (ArmGetRegister(Line,RetLen,Vars.rd) == false) return false;
				if (*(SourceEncoding+1) == '1' && Vars.rd.Number == 15) return false;
				Line += RetLen;
				SourceEncoding += 2;
				break;
			case 's':	// reg
				if (ArmGetRegister(Line,RetLen,Vars.rs) == false) return false;
				if (*(SourceEncoding+1) == '1' && Vars.rs.Number == 15) return false;
				Line += RetLen;
				SourceEncoding += 2;
				break;
			case 'n':	// reg
				if (ArmGetRegister(Line,RetLen,Vars.rn) == false) return false;
				if (*(SourceEncoding+1) == '1' && Vars.rn.Number == 15) return false;
				Line += RetLen;
				SourceEncoding += 2;
				break;
			case 'm':	// reg
				if (ArmGetRegister(Line,RetLen,Vars.rm) == false) return false;
				if (*(SourceEncoding+1) == '1' && Vars.rm.Number == 15) return false;
				Line += RetLen;
				SourceEncoding += 2;
				break;*/
			case 'W':	// writeback
				if (*Line == '!')
				{
					Vars.writeback = true;
					Line++;
				}
				SourceEncoding++;
				break;
			case 'p':	// psr
				if (*Line == '^')
				{
					Vars.psr = true;
					Line++;
				}
				SourceEncoding++;
				break;
			case 'P':	// msr/mrs psr data
				if (strncmp(Line,"cpsr",4) == 0)	// is cpsr
				{
					Vars.PsrData.spsr = false;
					Line += 4;
				} else if (strncmp(Line,"spsr",4) == 0)	// is spsr
				{
					Vars.PsrData.spsr = true;
					Line += 4;
				} else return false;		// otherwise it's neither

				if (SourceEncoding[1] != '1')
				{
					if (*Line != '_')		// no underscore = short version
					{
						Vars.PsrData.field = 0xF;
					} else {
						Line++;
						if (memcmp(Line,"ctl",3) == 0)
						{
							Vars.PsrData.field = 1;
							Line += 3;
						} else if (memcmp(Line,"flg",3) == 0)
						{
							Vars.PsrData.field = 8;
							Line += 3;
						} else {
							Vars.PsrData.field = 0;
							for (int i = 0; i < 4; i++)
							{
								if (*Line == ',') break;
								if (*Line == 'f')
								{
									if (Vars.PsrData.field & 8) return false;	// can only appear once
									Vars.PsrData.field |= 8;
								} else if (*Line == 's')
								{
									if (Vars.PsrData.field & 4) return false;	// can only appear once
									Vars.PsrData.field |= 4;
								} else if (*Line == 'x')
								{
									if (Vars.PsrData.field & 2) return false;	// can only appear once
									Vars.PsrData.field |= 2;
								} else if (*Line == 'c')
								{
									if (Vars.PsrData.field & 1) return false;	// can only appear once
									Vars.PsrData.field |= 1;
								} else return false;	// has to be one of those
								Line++;
							}
						}
					}
				}
				SourceEncoding+=2;
				break;
			case 'R':	// rlist
				if (ArmGetRlist(Line,RetLen,0xFFFF,Vars.rlist) == false) return false;
				memcpy(Vars.RlistStr,Line,RetLen);
				Vars.RlistStr[RetLen] = 0;
				Line += RetLen;
				SourceEncoding++;
				break;
			case 'S':
				if (ParseShift(Line,SourceEncoding[1]) == false) return false;
				SourceEncoding += 2;
				break;
			case 'I':	// immediate
			case 'i':
				if (ArmParseImmediate(Line,Vars.ImmediateExpression,RetLen) == false) return false;
				Line += RetLen;
				Vars.ImmediateBitLen = 32;
				SourceEncoding++;
				break;
			case 'j':	// variable bit immediate
				if (ArmParseImmediate(Line,Vars.ImmediateExpression,RetLen) == false) return false;
				Line += RetLen;
				Vars.ImmediateBitLen = *(SourceEncoding+1);
				SourceEncoding+=2;
				break;
			case '/':	// optional character
				if (*Line == *(SourceEncoding+1)) Line++;
				SourceEncoding += 2;
				break;
/*			case 'D':	// cop register d
				if (ArmGetCopRegister(Line,RetLen,Vars.CopData.cd) == false) return false;
				Line += RetLen;
				SourceEncoding++;
				break;
			case 'N':	// cop register n
				if (ArmGetCopRegister(Line,RetLen,Vars.CopData.cn) == false) return false;
				Line += RetLen;
				SourceEncoding++;
				break;
			case 'M':	// cop register m
				if (ArmGetCopRegister(Line,RetLen,Vars.CopData.cm) == false) return false;
				Line += RetLen;
				SourceEncoding++;
				break;*/
			case 'X':	// cop number
				if (ArmGetCopNumber(Line,RetLen,Vars.CopData.pn) == false) return false;
				Line += RetLen;
				SourceEncoding++;
				break;
			case 'Y':	// cop opcode number
				if (ArmParseImmediate(Line,Vars.CopData.CpopExpression,RetLen) == false)
				{
					Logger::printError(Logger::Error,L"Invalid expression");
					NoCheckError = true;
					return false;
				}
				Vars.ImmediateBitLen = 4;
				Line += RetLen;
				SourceEncoding++;
				break;
			case 'Z':	// cop info number
				if (ArmParseImmediate(Line,Vars.CopData.CpinfExpression,RetLen) == false)
				{
					Logger::printError(Logger::Error,L"Invalid expression");
					NoCheckError = true;
					return false;
				}
				Vars.ImmediateBitLen = 3;
				Line += RetLen;
				SourceEncoding++;
				break;
			case 'z':	// shift for pseudo opcodes
				Vars.Shift.Type = SourceEncoding[1];
				if (ArmGetRegister(Line,RetLen,Vars.Shift.reg) == true)	// shift by register
				{
					Vars.Shift.ShiftByRegister = true;
				} else {	// shift by immediate
					Vars.Shift.ShiftByRegister = false;
					if (ArmParseImmediate(Line,Vars.Shift.ShiftExpression,RetLen) == false)
					{
						Logger::printError(Logger::Error,L"Invalid shift expression");
						NoCheckError = true;
						return false;
					}
				}
				Line += RetLen;
				Vars.Shift.UseShift = true;
				SourceEncoding += 2;
				break;
			case 'v':	// sign for register index parameter
				if (*Line == '-')
				{
					Vars.SignPlus = false;
					Line++;
				} else if (*Line == '+')
				{
					Vars.SignPlus = true;
					Line++;
				} else {
					Vars.SignPlus = true;
				}
				SourceEncoding++;
				break;
			default:	// everything else
				if (*SourceEncoding++ != *Line++) return false;
				break;
			}
		}
	}

	while (*Line == ' ' || *Line == '\t') Line++;
	if (*Line != 0)	return false;	// there's something left, bad

	// opcode is fine - now set all flags
	Opcode = SourceOpcode;
	return true;
}