コード例 #1
0
ファイル: NasmInsns.cs プロジェクト: MrTrillian/Asmuth
		private static void ParseFlags(NasmInsnsEntry.Builder entryBuilder, string str)
		{
			if (str == "ignore") return;
			foreach (var flagStr in str.Split(','))
			{
				var enumerantName = char.IsDigit(flagStr[0]) ? '_' + flagStr : flagStr;
				var flag = (NasmInstructionFlag)Enum.Parse(typeof(NasmInstructionFlag), enumerantName, ignoreCase: true);
				entryBuilder.Flags.Add(flag);
			}
		}
コード例 #2
0
ファイル: NasmInsns.cs プロジェクト: MrTrillian/Asmuth
		private static void ParseVex(NasmInsnsEntry.Builder entryBuilder, string str)
		{
			var tokens = str.ToLowerInvariant().Split('.');
			int tokenIndex = 0;

			VexOpcodeEncoding encoding = 0;
			switch (tokens[tokenIndex++])
			{
				case "vex": encoding |= VexOpcodeEncoding.Type_Vex; break;
				case "xop": encoding |= VexOpcodeEncoding.Type_Xop; break;
				case "evex": encoding |= VexOpcodeEncoding.Type_EVex; break;
				default: throw new FormatException();
			}

			if (tokens[tokenIndex][0] == 'm')
			{
				// AMD-Style
				// xop.m8.w0.nds.l0.p0
				// vex.m3.w0.nds.l0.p1
				ParseVex_Map(ref encoding, tokens, ref tokenIndex);
				ParseVex_RexW(ref encoding, tokens, ref tokenIndex);
				ParseVex_Vvvv(ref encoding, tokens, ref tokenIndex);
				ParseVex_VectorLength(ref encoding, tokens, ref tokenIndex);
				ParseVex_SimdPrefix_AmdStyle(ref encoding, tokens, ref tokenIndex);
			}
			else
			{
				// Intel-Style
				// vex.nds.256.66.0f3a.w0
				// evex.nds.512.66.0f3a.w0
				ParseVex_Vvvv(ref encoding, tokens, ref tokenIndex);
				ParseVex_VectorLength(ref encoding, tokens, ref tokenIndex);
				ParseVex_SimdPrefix_IntelStyle(ref encoding, tokens, ref tokenIndex);
				ParseVex_Map(ref encoding, tokens, ref tokenIndex);
				ParseVex_RexW(ref encoding, tokens, ref tokenIndex);
			}

			entryBuilder.EncodingTokens.Add(NasmEncodingTokenType.Vex);
			entryBuilder.VexEncoding = encoding;
		}
コード例 #3
0
ファイル: NasmInsns.cs プロジェクト: MrTrillian/Asmuth
		private static void ParseOperands(NasmInsnsEntry.Builder entryBuilder, string fieldsString, string valuesString)
		{
			if (valuesString == "void" || valuesString == "ignore")
			{
				Contract.Assert(fieldsString.Length == 0);
				return;
			}

			if (fieldsString.Length == 0)
			{
				// This only happens for pseudo-instructions
				return;
			}

			valuesString = valuesString.Replace("*", string.Empty); // '*' is for "relaxed", but it's not clear what this encodes
			var values = Regex.Split(valuesString, "[,:]");
			
			if (fieldsString == "r+mi")
			{
				// Hack around the IMUL special case
				fieldsString = "rmi";
				values = new[] { values[0], values[0].Replace("reg", "rm"), values[1] };
			}

			Contract.Assert(values.Length == fieldsString.Length);

			for (int i = 0; i < values.Length; ++i)
			{
				var field = ParseOperandField(fieldsString[i]);

				var valueComponents = values[i].Split('|');
				var typeString = valueComponents[0];
				var type = (NasmOperandType)Enum.Parse(typeof(NasmOperandType), valueComponents[0], ignoreCase: true);
				entryBuilder.Operands.Add(new NasmOperand(field, type));
				// TODO: Parse NASM operand flags (after the '|')
				// TODO: Support star'ed types like "xmmreg*"
			}
		}
コード例 #4
0
ファイル: NasmInsns.cs プロジェクト: MrTrillian/Asmuth
		private static void ParseCodeString(NasmInsnsEntry.Builder entryBuilder, string str)
		{
			var tokens = str.Split(' ');
			int tokenIndex = 0;

			bool hasVex = false;
			while (tokenIndex < tokens.Length)
			{
				var token = tokens[tokenIndex++];

				var tokenType = NasmEncodingToken.TryParseType(token);
				if (tokenType != NasmEncodingTokenType.None)
				{
					entryBuilder.EncodingTokens.Add(tokenType);
					continue;
				}

				byte @byte;
				if (Regex.IsMatch(token, @"\A[0-9a-f]{2}(\+[rc])?\Z")
					&& byte.TryParse(token.Substring(0, 2), NumberStyles.HexNumber, CultureInfo.InvariantCulture, out @byte))
				{
					var type = NasmEncodingTokenType.Byte;
					if (token.Length == 4)
					{
						type = token[token.Length - 1] == 'r'
							? NasmEncodingTokenType.Byte_PlusRegister
							: NasmEncodingTokenType.Byte_PlusConditionCode;
					}
					entryBuilder.EncodingTokens.Add(new NasmEncodingToken(type, @byte));
					continue;
				}

				if (Regex.IsMatch(token, @"\A/[0-7]\Z"))
				{
					entryBuilder.EncodingTokens.Add(new NasmEncodingToken(NasmEncodingTokenType.ModRM_FixedReg, (byte)(token[1] - '0')));
					continue;
				}

				if (Regex.IsMatch(token, @"\A(vex|xop|evex)\."))
				{
					Contract.Assert(!hasVex);
					ParseVex(entryBuilder, token);
					hasVex = true;
					continue;
				}

				throw new FormatException("Unexpected NASM encoding token '{0}'".FormatInvariant(token));
			}
		}