/// <summary> /// Instruction mapping for op codes and such for using in encoding /// </summary> public InstructionMap() { table = CodeTable.DefaultTable; firstMap = new OpcodeMap((int)VCDiffInstructionType.LAST + AddressCache.DefaultLast + 1, FindMaxSize(table.size1)); secondMap = new OpcodeMap2((int)VCDiffInstructionType.LAST + AddressCache.DefaultLast + 1, FindMaxSize(table.size2)); for (int opcode = 0; opcode < CodeTable.kCodeTableSize; ++opcode) { if (table.inst2[opcode] == CodeTable.N) { firstMap.Add(table.inst1[opcode], table.size1[opcode], table.mode1[opcode], (byte)opcode); } else if (table.inst1[opcode] == CodeTable.N) { firstMap.Add(table.inst1[opcode], table.size1[opcode], table.mode1[opcode], (byte)opcode); } } for (int opcode = 0; opcode < CodeTable.kCodeTableSize; ++opcode) { if ((table.inst1[opcode] != CodeTable.N) && (table.inst2[opcode] != CodeTable.N)) { int found = LookFirstOpcode(table.inst1[opcode], table.size1[opcode], table.mode1[opcode]); if (found == CodeTable.kNoOpcode) { continue; } secondMap.Add((byte)found, table.inst2[opcode], table.size2[opcode], table.mode2[opcode], (byte)opcode); } } }
public byte[] ToBytes(OpcodeMap opcodeMap) { var result = ToBytes(); result[0] = opcodeMap.Map[Opcode].Value; return(result); }
private void Write(OpcodeMap map) { switch (map) { case OpcodeMap.Default: break; case OpcodeMap.Escape0F: stream.WriteByte(0x0F); break; case OpcodeMap.Escape0F38: stream.WriteByte(0x0F); stream.WriteByte(0x38); break; case OpcodeMap.Escape0F3A: stream.WriteByte(0x0F); stream.WriteByte(0x3A); break; default: throw new ArgumentOutOfRangeException(nameof(map)); } }
private void Decode() { var code = _ram[_registers.PC]; var opcode = OpcodeMap.GetOpcode(code); var disassembler = new Disassembler(this); var instruction = disassembler.Decode(opcode, _ram[_registers.PC, _registers.PC + opcode.Bytes]); instruction.Item1.Invoke(this, instruction.Item2); _registers.PC += opcode.Bytes; }
private void Emit(OpcodeMap map, byte opcode8, byte opcode, Gpr reg, EffectiveAddress rm) { WritePrefixes(reg, rm); Emit(map, reg.Size == OperandSize.Byte ? opcode8 : opcode); var displacementSize = rm.MinimumDisplacementSize; var encoding = rm.Encode( context.GetDefaultAddressSize(), reg.Code.GetLow3Bits(), displacementSize); Write(encoding.ModRM); if (encoding.Sib.HasValue) Write(encoding.Sib.Value); switch (displacementSize) { case DisplacementSize._8: Write((sbyte)encoding.Displacement); break; case DisplacementSize._16: Write((short)encoding.Displacement); break; case DisplacementSize._32: Write(encoding.Displacement); break; } }
private InstructionModel WrapInstruction(Instruction instruction, OpcodeMap opcodeMap) { var foreground = Brushes.Black; if (!instruction.Enabled) { foreground = Brushes.LightGray; } if (instruction is Comment) { foreground = Brushes.Green; } return(new InstructionModel() { Foreground = foreground, Text = instruction.ToListing(opcodeMap) }); }
/// <summary> /// Instruction mapping for op codes and such for using in encoding /// </summary> public unsafe InstructionMap() { table = CodeTable.DefaultTable; var inst2 = table.inst2; var inst1 = table.inst1; var size2 = table.size2; var size1 = table.size1; var mode1 = table.mode1; var mode2 = table.mode2; // max sizes are known for the default code table (18 and 6 respectively). firstMap = new OpcodeMap((int)VCDiffInstructionType.LAST + AddressCache.DefaultLast + 1, FindMaxSize(size1.AsSpan(), 18)); secondMap = new OpcodeMap2((int)VCDiffInstructionType.LAST + AddressCache.DefaultLast + 1, FindMaxSize(size2.AsSpan(), 6)); for (int opcode = 0; opcode < CodeTable.kCodeTableSize; ++opcode) { if (inst2.Pointer[opcode] == CodeTable.N) { firstMap.Add(inst1.Pointer[opcode], size1.Pointer[opcode], mode1.Pointer[opcode], (byte)opcode); } else if (inst1.Pointer[opcode] == CodeTable.N) { firstMap.Add(inst1.Pointer[opcode], size1.Pointer[opcode], mode1.Pointer[opcode], (byte)opcode); } } for (int opcode = 0; opcode < CodeTable.kCodeTableSize; ++opcode) { if ((inst1.Pointer[opcode] != CodeTable.N) && (inst2.Pointer[opcode] != CodeTable.N)) { int found = LookFirstOpcode(inst1.Pointer[opcode], size1.Pointer[opcode], mode1.Pointer[opcode]); if (found == CodeTable.kNoOpcode) { continue; } secondMap.Add((byte)found, inst2.Pointer[opcode], size2.Pointer[opcode], mode2.Pointer[opcode], (byte)opcode); } } }
public virtual string ToListing(OpcodeMap opcodeMap) { var builder = new StringBuilder(); var bytes = ToBytes(opcodeMap); foreach (var b in bytes) { builder.Append(b.ToString("x2")); builder.Append(" "); } while (builder.Length < 16) { builder.Append(' '); } builder.Append(Mnemonic); builder.Append(' '); builder.Append(string.Join(", ", Arguments)); return(builder.ToString()); }
public Code(LFunction function) { code = function.Code; map = function.Header.Version.GetOpcodeMap(); }
private void Emit(OpcodeMap map, byte opcode) { Write(map); Write(opcode); }
private void CompileOnClick(object sender, RoutedEventArgs e) { var start = Environment.TickCount; var compiler = new Compiler(); compiler.Compile(Model.Input.Split(new[] { Environment.NewLine }, StringSplitOptions.None)); var optimizer = new Optimizer(); optimizer.Optimize(compiler.Instructions); var opcodeMap = new OpcodeMap(); opcodeMap.AssignOpcodesByFrequency(compiler.Instructions); Model.ParameterSlots = string.Join(Environment.NewLine, compilerSettings.ParameterSlots.Select( entry => string.Format("{0}{1}", entry.Key.PadRight(30, '.'), entry.Value))); var usedOpcodes = new HashSet <byte>(compiler.Instructions.Select(i => opcodeMap.Map[i.Opcode].Value)); Model.Opcodes = opcodeMap.Map.Values.Select( entry => new OpcodeModel(entry.Name.PadRight(30, '.'), entry.Value, usedOpcodes.Contains(entry.Value) ? Brushes.Black : Brushes.Silver)).ToList(); Model.Output = compiler.Instructions.Select(i => WrapInstruction(i, opcodeMap)).ToList(); Model.FloatConsts = string.Join(Environment.NewLine, compiler.FloatConsts.Values.Select(v => v.ToString(CultureInfo.InvariantCulture))); Model.IntConsts = string.Join(Environment.NewLine, compiler.IntConsts.Values.Select(v => v.ToString(CultureInfo.InvariantCulture))); Model.TickConsts = string.Join(Environment.NewLine, compiler.TickConsts.Values.Select(v => v.ToString(CultureInfo.InvariantCulture))); Model.UnoptimizedBytes = compiler.Instructions.Sum(i => i.ToBytes().Length); Model.OptimizedBytes = compiler.Instructions.Where(i => i.Enabled).Sum(i => i.ToBytes().Length); var statistics = new Statistics(compiler); var optimizedByteFrequencies = statistics.OptimizedByteFrequencies.ToFrequencies(); var unoptimizedByteFrequencies = statistics.UnoptimizedByteFrequencies.ToFrequencies(); var bytecodeStatistics = statistics .AllBytes .Select(b => new StatisticsModel <byte>(b, optimizedByteFrequencies[b], unoptimizedByteFrequencies[b])) .ToList(); Model.BytecodeStatistics = bytecodeStatistics; var optimizedOpcodeFrequencies = new Frequencies( compiler.Instructions.Where(i => i.Enabled && !(i is Comment)) .Select(i => (byte)i.Opcode) .ToArray()); var opcodeStatistics = optimizedOpcodeFrequencies .ToFrequencies() .Select(entry => new StatisticsModel <string>(((Opcodes)entry.Key).ToString(), entry.Value, 0)) .OrderBy(m => - m.OptimizedFrequency) .ToList(); Model.OpcodeStatistics = opcodeStatistics; var end = Environment.TickCount; Model.CompileTime = end - start; }
public static void LoadHandlers() { var types = Assembly.GetExecutingAssembly().GetTypes(); var identifiedClientBuilds = new List <uint>(); _serverPacketHandlers = new HandlerMap(); _clientPacketHandlers = new HandlerMap(); _serverOpcodeMap = new OpcodeMap(); _clientOpcodeMap = new OpcodeMap(); foreach (var type in types) { if (!type.IsAbstract || !type.IsPublic) { continue; } // Require each handler class to define the client build. var classAttributes = (ClientBuildAttribute[])type.GetCustomAttributes(typeof(ClientBuildAttribute), false); if (classAttributes.Length == 0) { continue; } var clientBuild = classAttributes[0].ClientBuild; var methods = type.GetMethods(); foreach (var method in methods) { if (!method.IsPublic) { continue; } var parameters = method.GetParameters(); if (parameters.Length == 0 || parameters[0].ParameterType != typeof(Packet)) { continue; } var attributes = (ParserAttribute[])method.GetCustomAttributes(typeof(ParserAttribute), false); if (attributes.Length == 0) { continue; } var attribute = attributes[0]; if (attribute.OpcodeValue == 0) { continue; } var key = CreateKey(clientBuild, attribute.OpcodeValue); var handler = (PacketHandler)Delegate.CreateDelegate(typeof(PacketHandler), method); OpcodeMap opcodeMap; HandlerMap handlerMap; if (attribute.Direction == Direction.ClientToServer) { opcodeMap = _clientOpcodeMap; handlerMap = _clientPacketHandlers; } else { opcodeMap = _serverOpcodeMap; handlerMap = _serverPacketHandlers; } if (handlerMap.ContainsKey(key)) { Debug.Print("Handler already found for opcode 0x{0:X4} ({1}) of client build {2}.", attribute.OpcodeValue, attribute.Opcode, clientBuild); continue; } if (!identifiedClientBuilds.Contains(clientBuild)) { identifiedClientBuilds.Add(clientBuild); } handlerMap[key] = handler; opcodeMap[key] = attribute.Opcode; Debug.Print("Handler added for opcode 0x{0:X4} ({1}) of client build {2}.", attribute.OpcodeValue, attribute.Opcode, clientBuild); } } // Now look through the builds we've discovered and identify their versions. foreach (var clientBuild in identifiedClientBuilds) { ClientVersion.AddAvailableVersion(clientBuild); } }
public override string ToListing(OpcodeMap opcodeMap) { return(string.Format("// {0}", line)); }
public static Opcode WithMap(this Opcode opcode, OpcodeMap map) => (opcode & ~Opcode.Map_Mask) | (Opcode)((uint)map << (int)Opcode.Map_Shift);
public static Opcode MakeLookupKey(SimdPrefix simdPrefix, OpcodeMap map, byte mainByte) { Contract.Requires(simdPrefix == SimdPrefix.None || map != OpcodeMap.Default); return default(Opcode) .WithSimdPrefix(simdPrefix) .WithMap(map) .WithMainByte(mainByte) & Opcode.LookupKey_Mask; }