public Result Disassemble(uint pc, Instruction instruction) { if (ProcessCallback == null) { var dictionary = new Dictionary <InstructionInfo, int>(); InstructionLookup = InstructionTable.All.ToArray(); for (var n = 0; n < InstructionLookup.Length; n++) { dictionary[InstructionLookup[n]] = n; } ProcessCallback = EmitLookupGenerator.GenerateSwitch <Func <uint, MipsDisassembler, Result> >("", InstructionTable.All, instructionInfo => ast.Return(ast.CallStatic( (Func <uint, int, Result>)_InternalHandle, ast.Argument <uint>(0), instructionInfo != null ? dictionary[instructionInfo] : -1 ))); } var result = ProcessCallback(instruction, this); if (result.InstructionInfo == null) { Console.Error.WriteLine( $"Instruction at 0x{pc:X8} with data 0x{(uint) instruction:X8} didn't generate a value"); result.InstructionInfo = InstructionTable.Unknown; } result.InstructionPc = pc; return(result); }
public void GenerateSwitchDelegateTest() { var EmitLookupGenerator = new EmitLookupGenerator(); var Callback = EmitLookupGenerator.GenerateSwitchDelegate <HandlerClass>(new InstructionInfo[] { new InstructionInfo() { BinaryEncoding = "----------------------------0001", Name = "test1" }, new InstructionInfo() { BinaryEncoding = "----------------------------0010", Name = "test2" }, new InstructionInfo() { BinaryEncoding = "----------------------------01--", Name = "test3" }, }); var HandlerClass = new HandlerClass(); Callback(Convert.ToUInt32("0000", 2), HandlerClass); Callback(Convert.ToUInt32("0001", 2), HandlerClass); Callback(Convert.ToUInt32("0010", 2), HandlerClass); Callback(Convert.ToUInt32("0011", 2), HandlerClass); Callback(Convert.ToUInt32("0100", 2), HandlerClass); Callback(Convert.ToUInt32("0110", 2), HandlerClass); Callback(Convert.ToUInt32("1110", 2), HandlerClass); Assert.AreEqual("0,1,2,0,3,3,0", String.Join(",", HandlerClass.Values)); }
public void GenerateSwitchDelegateTest() { var EmitLookupGenerator = new EmitLookupGenerator(); var Callback = EmitLookupGenerator.GenerateSwitchDelegate<HandlerClass>(new InstructionInfo[] { new InstructionInfo() { BinaryEncoding = "----------------------------0001", Name = "test1" }, new InstructionInfo() { BinaryEncoding = "----------------------------0010", Name = "test2" }, new InstructionInfo() { BinaryEncoding = "----------------------------01--", Name = "test3" }, }); var HandlerClass = new HandlerClass(); Callback(Convert.ToUInt32("0000", 2), HandlerClass); Callback(Convert.ToUInt32("0001", 2), HandlerClass); Callback(Convert.ToUInt32("0010", 2), HandlerClass); Callback(Convert.ToUInt32("0011", 2), HandlerClass); Callback(Convert.ToUInt32("0100", 2), HandlerClass); Callback(Convert.ToUInt32("0110", 2), HandlerClass); Callback(Convert.ToUInt32("1110", 2), HandlerClass); Assert.AreEqual("0,1,2,0,3,3,0", String.Join(",", HandlerClass.Values)); }
public MipsDisassembler() { ProcessCallback = EmitLookupGenerator.GenerateSwitchDelegate <MipsDisassembler>(InstructionTable.ALL, (ILGenerator ILGenerator, InstructionInfo InstructionInfo) => { ILGenerator.Emit(OpCodes.Ldstr, InstructionInfo.Name); ILGenerator.Emit(OpCodes.Call, typeof(MipsAssembler).GetMethod("Handle")); }); }
static Action <uint, CpuInterpreter> GenerateSwitch() { var CIType = typeof(CpuInterpreter); var nameToInfo = new Dictionary <string, MethodInfo>(); foreach (var methodInfo in CIType.GetMethods()) { var instructionNames = methodInfo.GetSingleAttribute <InstructionName>(); if (instructionNames != null) { nameToInfo[instructionNames.Name] = methodInfo; } } return(EmitLookupGenerator.GenerateSwitch <Action <uint, CpuInterpreter> >(nameof(CpuInterpreterSwitchGenerator), InstructionTable.All, instructionInfo => { var methodInfo = nameToInfo[InstructionNames.Unknown]; if (instructionInfo != null && nameToInfo.ContainsKey(instructionInfo.Name)) { methodInfo = nameToInfo[instructionInfo.Name]; } Console.WriteLine($"{methodInfo} {instructionInfo}"); if (methodInfo == null) { } return Ast.Statements( Ast.Statement(Ast.CallInstance(Ast.Argument <CpuInterpreter>(1), methodInfo)), Ast.Return() ); } )); }
public void GenerateSwitchDelegateTest() { // ReSharper disable once ObjectCreationAsStatement new EmitLookupGenerator(); var callback = EmitLookupGenerator.GenerateSwitchDelegate <HandlerClass>("GenerateSwitchDelegateTest", new[] { new InstructionInfo() { BinaryEncoding = "----------------------------0001", Name = "test1" }, new InstructionInfo() { BinaryEncoding = "----------------------------0010", Name = "test2" }, new InstructionInfo() { BinaryEncoding = "----------------------------01--", Name = "test3" }, }); var handlerClass = new HandlerClass(); callback(Convert.ToUInt32("0000", 2), handlerClass); callback(Convert.ToUInt32("0001", 2), handlerClass); callback(Convert.ToUInt32("0010", 2), handlerClass); callback(Convert.ToUInt32("0011", 2), handlerClass); callback(Convert.ToUInt32("0100", 2), handlerClass); callback(Convert.ToUInt32("0110", 2), handlerClass); callback(Convert.ToUInt32("1110", 2), handlerClass); Assert.Equal("0,1,2,0,3,3,0", string.Join(",", handlerClass.Values)); }