<commit_before>﻿/*
    Copyright (C) 2018 <EMAIL>

    This file is part of Iced.

    Iced is free software: you can redistribute it and/or modify
    it under the terms of the GNU Lesser General Public License as published by
    the Free Software Foundation, either version 3 of the License, or
    (at your option) any later version.

    Iced is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU Lesser General Public License for more details.

    You should have received a copy of the GNU Lesser General Public License
    along with Iced.  If not, see <https://www.gnu.org/licenses/>.
*/

using System;
using System.Diagnostics;
using System.Runtime.CompilerServices;
using System.Text;

namespace Iced.Intel {
	/// <summary>
	/// A 16/32/64-bit instruction
	/// </summary>
	public partial struct Instruction {
		internal const int TEST_OpKindBits = (int)OpKindFlags.OpKindBits;
		internal const int TEST_CodeBits = (int)CodeFlags.CodeBits;
		internal const int TEST_RegisterBits = 8;

		/// <summary>
		/// [1:0]	= Scale
		/// [4:2]	= Size of displacement: 0, 1, 2, 4, 8
		/// [7:5]	= Segment register prefix: none, es, cs, ss, ds, fs, gs, reserved
		/// [14:8]	= Not used
		/// [15]	= Broadcasted memory
		/// </summary>
		[Flags]
		enum MemoryFlags : ushort {
			ScaleMask				= 3,
			DisplSizeShift			= 2,
			DisplSizeMask			= 7,
			PrefixSegmentShift		= 5,
			PrefixSegmentMask		= 7,
			MemorySizeBits			= 7,
			// Unused bits here
			BroadcastedMemory		= 0x8000,
		}

		/// <summary>
		/// [4:0]	= Operand #0's <see cref="OpKind"/>
		/// [9:5]	= Operand #1's <see cref="OpKind"/>
		/// [14:10]	= Operand #2's <see cref="OpKind"/>
		/// [19:15]	= Operand #3's <see cref="OpKind"/>
		/// [29:20]	= Not used
		/// [31:30] = CodeSize
		/// </summary>
		[Flags]
		enum OpKindFlags : uint {
			OpKindBits				= 5,
			OpKindMask				= (1 << (int)OpKindBits) - 1,
			Op1KindShift			= 5,
			Op2KindShift			= 10,
			Op3KindShift			= 15,
			// Unused bits here
			CodeSizeMask			= 3,
			CodeSizeShift			= 30,
		}

		/// <summary>
		/// [11:0]	= <see cref="Intel.Code"/>
		/// [12]	= Not used
		/// [15:13]	= <see cref="Intel.RoundingControl"/>
		/// [18:16]	= Opmask register or 0 if none
		/// [22:19]	= Instruction length
		/// [24:23] = Not used
		/// [25]	= Suppress all exceptions
		/// [26]	= Zeroing masking
		/// [27]	= xacquire prefix
		/// [28]	= xrelease prefix
		/// [29]	= repe prefix
		/// [30]	= repne prefix
		/// [31]	= lock prefix
		/// </summary>
		[Flags]
		enum CodeFlags : uint {
			CodeBits				= 12,
			CodeMask				= (1 << (int)CodeBits) - 1,
			RoundingControlMask		= 7,
			RoundingControlShift	= 13,
			OpMaskMask				= 7,
			OpMaskShift				= 16,
			InstrLengthMask			= 0xF,
			InstrLengthShift		= 19,
			// Unused bits here
			SuppressAllExceptions	= 0x02000000,
			ZeroingMasking			= 0x04000000,
			PrefixXacquire			= 0x08000000,
			PrefixXrelease			= 0x10000000,
			PrefixRepe				= 0x20000000,
			PrefixRepne				= 0x40000000,
			PrefixLock				= 0x80000000,
		}

		// All fields, size: 32 bytes with bits to spare
		// Next RIP is only needed by RIP relative memory operands. Without this field the user would have
		// to pass this value to the formatter and encoder methods.
		ulong nextRip;
		uint codeFlags;// CodeFlags
		uint opKindFlags;// OpKindFlags
		// If it's a 64-bit immediate/offset/target, the high 32 bits is in memDispl
		uint immediate;
		// This is the high 32 bits if it's a 64-bit immediate/offset/target
		uint memDispl;
		ushort memoryFlags;// MemoryFlags
		byte memBaseReg;// Register
		byte memIndexReg;// Register
		// If a Register will need 9 bits in the future, it's probably best to turn this into a
		// uint (and move it below the other uint fields above). The remaining 4 bits of 'reg3'
		// can be stored in some other field (it's rarely used)
		byte reg0, reg1, reg2, reg3;// Register

		internal static bool TEST_BitByBitEquals(ref Instruction a, ref Instruction b) =>
			a.nextRip == b.nextRip &&
			a.codeFlags == b.codeFlags &&
			a.opKindFlags == b.opKindFlags &&
			a.immediate == b.immediate &&
			a.memDispl == b.memDispl &&
			a.memoryFlags == b.memoryFlags &&
			a.memBaseReg == b.memBaseReg &&
			a.memIndexReg == b.memIndexReg &&
			a.reg0 == b.reg0 &&
			a.reg1 == b.reg1 &&
			a.reg2 == b.reg2 &&
			a.reg3 == b.reg3;

		internal static string TEST_DumpDiff(ref Instruction a, ref Instruction b) {
			var builder = new StringBuilder();
			if (a.nextRip != b.nextRip)
				builder.AppendLine("a.nextRip=" + a.nextRip + " b.nextRip=" + b.nextRip);
			if (a.codeFlags != b.codeFlags)
				builder.AppendLine("a.codeFlags=" + a.codeFlags + " b.codeFlags=" + b.codeFlags);
			if (a.opKindFlags != b.opKindFlags)
				builder.AppendLine("a.opKindFlags=" + a.opKindFlags + " b.opKindFlags=" + b.opKindFlags);
			if (a.immediate != b.immediate)
				builder.AppendLine("a.immediate=" + a.immediate + " b.immediate=" + b.immediate);
			if (a.memDispl != b.memDispl)
				builder.AppendLine("a.memDispl=" + a.memDispl + " b.memDispl=" + b.memDispl);
			if (a.memoryFlags != b.memoryFlags)
				builder.AppendLine("a.memoryFlags=" + a.memoryFlags + " b.memoryFlags=" + b.memoryFlags);
			if (a.MemoryBase != b.MemoryBase)
				builder.AppendLine("a.MemoryBase=" + a.MemoryBase + " b.MemoryBase=" + b.MemoryBase);
			if (a.MemoryIndex != b.MemoryIndex)
				builder.AppendLine("a.MemoryIndex=" + a.MemoryIndex + " b.MemoryIndex=" + b.MemoryIndex);
			if (a.Op0Register != b.Op0Register)
				builder.AppendLine("a.Op0Register=" + a.Op0Register + " b.Op0Register=" + b.Op0Register);
			if (a.Op1Register != b.Op1Register)
				builder.AppendLine("a.Op1Register=" + a.Op1Register + " b.Op1Register=" + b.Op1Register);
			if (a.Op2Register != b.Op2Register)
				builder.AppendLine("a.Op2Register=" + a.Op2Register + " b.Op2Register=" + b.Op2Register);
			if (a.Op3Register != b.Op3Register)
				builder.AppendLine("a.Op3Register=" + a.Op3Register + " b.Op3Register=" + b.Op3Register);
			return builder.ToString();
		}

		void ThrowArgumentOutOfRangeException(string paramName) => throw new ArgumentOutOfRangeException(paramName);
		void ThrowArgumentNullException(string paramName) => throw new ArgumentNullException(paramName);

		/// <summary>
		/// 16-bit IP of the instruction
		/// </summary>
		public ushort IP16 {
			get => (ushort)((uint)nextRip - (uint)ByteLength);
			set => nextRip = value + (uint)ByteLength;
		}

		/// <summary>
		/// 32-bit IP of the instruction
		/// </summary>
		public uint IP32 {
			get => (uint)nextRip - (uint)ByteLength;
			set => nextRip = value + (uint)ByteLength;<commit_msg>Use interpolated strings<commit_after>﻿/*
    Copyright (C) 2018 <EMAIL>

    This file is part of Iced.

    Iced is free software: you can redistribute it and/or modify
    it under the terms of the GNU Lesser General Public License as published by
    the Free Software Foundation, either version 3 of the License, or
    (at your option) any later version.

    Iced is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU Lesser General Public License for more details.

    You should have received a copy of the GNU Lesser General Public License
    along with Iced.  If not, see <https://www.gnu.org/licenses/>.
*/

using System;
using System.Diagnostics;
using System.Runtime.CompilerServices;
using System.Text;

namespace Iced.Intel {
	/// <summary>
	/// A 16/32/64-bit instruction
	/// </summary>
	public partial struct Instruction {
		internal const int TEST_OpKindBits = (int)OpKindFlags.OpKindBits;
		internal const int TEST_CodeBits = (int)CodeFlags.CodeBits;
		internal const int TEST_RegisterBits = 8;

		/// <summary>
		/// [1:0]	= Scale
		/// [4:2]	= Size of displacement: 0, 1, 2, 4, 8
		/// [7:5]	= Segment register prefix: none, es, cs, ss, ds, fs, gs, reserved
		/// [14:8]	= Not used
		/// [15]	= Broadcasted memory
		/// </summary>
		[Flags]
		enum MemoryFlags : ushort {
			ScaleMask				= 3,
			DisplSizeShift			= 2,
			DisplSizeMask			= 7,
			PrefixSegmentShift		= 5,
			PrefixSegmentMask		= 7,
			MemorySizeBits			= 7,
			// Unused bits here
			BroadcastedMemory		= 0x8000,
		}

		/// <summary>
		/// [4:0]	= Operand #0's <see cref="OpKind"/>
		/// [9:5]	= Operand #1's <see cref="OpKind"/>
		/// [14:10]	= Operand #2's <see cref="OpKind"/>
		/// [19:15]	= Operand #3's <see cref="OpKind"/>
		/// [29:20]	= Not used
		/// [31:30] = CodeSize
		/// </summary>
		[Flags]
		enum OpKindFlags : uint {
			OpKindBits				= 5,
			OpKindMask				= (1 << (int)OpKindBits) - 1,
			Op1KindShift			= 5,
			Op2KindShift			= 10,
			Op3KindShift			= 15,
			// Unused bits here
			CodeSizeMask			= 3,
			CodeSizeShift			= 30,
		}

		/// <summary>
		/// [11:0]	= <see cref="Intel.Code"/>
		/// [12]	= Not used
		/// [15:13]	= <see cref="Intel.RoundingControl"/>
		/// [18:16]	= Opmask register or 0 if none
		/// [22:19]	= Instruction length
		/// [24:23] = Not used
		/// [25]	= Suppress all exceptions
		/// [26]	= Zeroing masking
		/// [27]	= xacquire prefix
		/// [28]	= xrelease prefix
		/// [29]	= repe prefix
		/// [30]	= repne prefix
		/// [31]	= lock prefix
		/// </summary>
		[Flags]
		enum CodeFlags : uint {
			CodeBits				= 12,
			CodeMask				= (1 << (int)CodeBits) - 1,
			RoundingControlMask		= 7,
			RoundingControlShift	= 13,
			OpMaskMask				= 7,
			OpMaskShift				= 16,
			InstrLengthMask			= 0xF,
			InstrLengthShift		= 19,
			// Unused bits here
			SuppressAllExceptions	= 0x02000000,
			ZeroingMasking			= 0x04000000,
			PrefixXacquire			= 0x08000000,
			PrefixXrelease			= 0x10000000,
			PrefixRepe				= 0x20000000,
			PrefixRepne				= 0x40000000,
			PrefixLock				= 0x80000000,
		}

		// All fields, size: 32 bytes with bits to spare
		// Next RIP is only needed by RIP relative memory operands. Without this field the user would have
		// to pass this value to the formatter and encoder methods.
		ulong nextRip;
		uint codeFlags;// CodeFlags
		uint opKindFlags;// OpKindFlags
		// If it's a 64-bit immediate/offset/target, the high 32 bits is in memDispl
		uint immediate;
		// This is the high 32 bits if it's a 64-bit immediate/offset/target
		uint memDispl;
		ushort memoryFlags;// MemoryFlags
		byte memBaseReg;// Register
		byte memIndexReg;// Register
		// If a Register will need 9 bits in the future, it's probably best to turn this into a
		// uint (and move it below the other uint fields above). The remaining 4 bits of 'reg3'
		// can be stored in some other field (it's rarely used)
		byte reg0, reg1, reg2, reg3;// Register

		internal static bool TEST_BitByBitEquals(ref Instruction a, ref Instruction b) =>
			a.nextRip == b.nextRip &&
			a.codeFlags == b.codeFlags &&
			a.opKindFlags == b.opKindFlags &&
			a.immediate == b.immediate &&
			a.memDispl == b.memDispl &&
			a.memoryFlags == b.memoryFlags &&
			a.memBaseReg == b.memBaseReg &&
			a.memIndexReg == b.memIndexReg &&
			a.reg0 == b.reg0 &&
			a.reg1 == b.reg1 &&
			a.reg2 == b.reg2 &&
			a.reg3 == b.reg3;

		internal static string TEST_DumpDiff(ref Instruction a, ref Instruction b) {
			var builder = new StringBuilder();
			if (a.nextRip != b.nextRip)
				builder.AppendLine($"a.nextRip={a.nextRip:X16} b.nextRip={b.nextRip:X16}");
			if (a.codeFlags != b.codeFlags)
				builder.AppendLine($"a.codeFlags={a.codeFlags:X} b.codeFlags={b.codeFlags:X}");
			if (a.opKindFlags != b.opKindFlags)
				builder.AppendLine($"a.opKindFlags={a.opKindFlags:X} b.opKindFlags={b.opKindFlags:X}");
			if (a.immediate != b.immediate)
				builder.AppendLine($"a.immediate={a.immediate:X} b.immediate={b.immediate:X}");
			if (a.memDispl != b.memDispl)
				builder.AppendLine($"a.memDispl={a.memDispl:X} b.memDispl={b.memDispl:X}");
			if (a.memoryFlags != b.memoryFlags)
				builder.AppendLine($"a.memoryFlags={a.memoryFlags:X} b.memoryFlags={b.memoryFlags:X}");
			if (a.MemoryBase != b.MemoryBase)
				builder.AppendLine($"a.MemoryBase={a.MemoryBase} b.MemoryBase={b.MemoryBase}");
			if (a.MemoryIndex != b.MemoryIndex)
				builder.AppendLine($"a.MemoryIndex={a.MemoryIndex} b.MemoryIndex={b.MemoryIndex}");
			if (a.Op0Register != b.Op0Register)
				builder.AppendLine($"a.Op0Register={a.Op0Register} b.Op0Register={b.Op0Register}");
			if (a.Op1Register != b.Op1Register)
				builder.AppendLine($"a.Op1Register={a.Op1Register} b.Op1Register={b.Op1Register}");
			if (a.Op2Register != b.Op2Register)
				builder.AppendLine($"a.Op2Register={a.Op2Register} b.Op2Register={b.Op2Register}");
			if (a.Op3Register != b.Op3Register)
				builder.AppendLine($"a.Op3Register={a.Op3Register} b.Op3Register={b.Op3Register}");
			return builder.ToString();
		}

		void ThrowArgumentOutOfRangeException(string paramName) => throw new ArgumentOutOfRangeException(paramName);
		void ThrowArgumentNullException(string paramName) => throw new ArgumentNullException(paramName);

		/// <summary>
		/// 16-bit IP of the instruction
		/// </summary>
		public ushort IP16 {
			get => (ushort)((uint)nextRip - (uint)ByteLength);
			set => nextRip = value + (uint)ByteLength;
		}

		/// <summary>
		/// 32-bit IP of the instruction
		/// </summary>
		public uint IP32 {
			get => (uint)nextRip - (uint)ByteLength;
			set => nextRip = value + (uint)ByteLength;
{'fraction_non_alphanumeric': 0.1397503923473582, 'fraction_numerical': 0.03706748374560945, 'mean_word_length': 3.056380721430737, 'pattern_counts': {'":': 0, '<': 51, '<?xml version=': 0, '>': 57, 'https://': 2, 'lorem ipsum': 0, 'www.': 2, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 8, 'word_list_counts': {'cursed_substrings.json': 2, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '5253445', 'n_tokens_mistral': 5555, 'n_tokens_neox': 4672, 'n_words': 1255}