void GenerateOpCodeOperandKindTables(OpCodeHandlers handlers) { var filename = CSharpConstants.GetFilename(genTypes, CSharpConstants.EncoderNamespace, "OpCodeOperandKinds.g.cs"); using (var writer = new FileWriter(TargetLanguage.CSharp, FileUtils.OpenWrite(filename))) { writer.WriteFileHeader(); writer.WriteLineNoIndent($"#if {CSharpConstants.OpCodeInfoDefine}"); writer.WriteLine($"namespace {CSharpConstants.EncoderNamespace} {{"); using (writer.Indent()) { writer.WriteLine("static class OpCodeOperandKinds {"); using (writer.Indent()) { Generate(writer, "LegacyOpKinds", null, handlers.Legacy); Generate(writer, "VexOpKinds", CSharpConstants.VexDefine, handlers.Vex); Generate(writer, "XopOpKinds", CSharpConstants.XopDefine, handlers.Xop); Generate(writer, "EvexOpKinds", CSharpConstants.EvexDefine, handlers.Evex); Generate(writer, "MvexOpKinds", CSharpConstants.MvexDefine, handlers.Mvex); } writer.WriteLine("}"); } writer.WriteLine("}"); writer.WriteLineNoIndent("#endif"); } void Generate(FileWriter writer, string name, string?define, (EnumValue opCodeOperandKind, OpHandlerKind opHandlerKind, object[] args)[] table)
/// <summary> /// Disassembles the current method and returns a list of /// disassembled instructions. /// </summary> /// <returns>The list of disassembled instructions.</returns> public DisassembledMethod Disassemble() { while (ilOffset < il.Length) { instructionOffset = ilOffset; var opCode = ReadOpCode(); if (debugInformationEnumerator.MoveTo(instructionOffset)) { CurrentSequencePoint = debugInformationEnumerator.Current; } if (PrefixHandlers.TryGetValue(opCode, out PrefixHandler prefixHandler)) { prefixHandler(this); } else if (OpCodeHandlers.TryGetValue(opCode, out OpCodeHandler opCodeHandler)) { // Handle operation opCodeHandler(this); // Reset flags flags = ILInstructionFlags.None; flagsArgument = null; } else { if (NotSupportedILInstruction == null) { throw new NotSupportedException(string.Format( ErrorMessages.NotSupportedILInstruction, MethodBase.Name, opCode)); } else { NotSupportedILInstruction(this, opCode); } } } return(new DisassembledMethod(MethodBase, instructions, MethodBody.MaxStackSize)); }
private void InitializeOpCodeHandlers() { adcOperation = new ADCOperation(); andOperation = new ANDOperation(); aslOperation = new ASLOperation(); bccOperation = new BCCOperation(); bcsOperation = new BCSOperation(); beqOperation = new BEQOperation(); bitOperation = new BITOperation(); bmiOperation = new BMIOperation(); bneOperation = new BNEOperation(); bplOperation = new BPLOperation(); bvcOperation = new BVCOperation(); bvsOperation = new BVSOperation(); clcOperation = new CLCOperation(); cldOperation = new CLDOperation(); cliOperation = new CLIOperation(); clvOperation = new CLVOperation(); cmpOperation = new CMPOperation(); cpxOperation = new CPXOperation(); cpyOperation = new CPYOperation(); decOperation = new DECOperation(); dexOperation = new DEXOperation(); deyOperation = new DEYOperation(); eorOperation = new EOROperation(); incOperation = new INCOperation(); inxOperation = new INXOperation(); inyOperation = new INYOperation(); jmpOperation = new JMPOperation(); jsrOperation = new JSROperation(); laxOperation = new LAXOperation(); ldaOperation = new LDAOperation(); ldxOperation = new LDXOperation(); ldyOperation = new LDYOperation(); lsrOperation = new LSROperation(); nopOperation = new NOPOperation(); oraOperation = new ORAOperation(); phaOperation = new PHAOperation(); phpOperation = new PHPOperation(); plaOperation = new PLAOperation(); plpOperation = new PLPOperation(); rolOperation = new ROLOperation(); rorOperation = new ROROperation(); rtiOperation = new RTIOperation(); rtsOperation = new RTSOperation(); sbcOperation = new SBCOperation(); secOperation = new SECOperation(); sedOperation = new SEDOperation(); seiOperation = new SEIOperation(); staOperation = new STAOperation(); stxOperation = new STXOperation(); styOperation = new STYOperation(); taxOperation = new TAXOperation(); tayOperation = new TAYOperation(); tsxOperation = new TSXOperation(); txaOperation = new TXAOperation(); txsOperation = new TXSOperation(); tyaOperation = new TYAOperation(); noneAddressingMode = new NoneAddressingMode(); absoluteAddressingMode = new AbsoluteAddressingMode(); absoluteXAddressingMode = new AbsoluteXAddressingMode(); absoluteYAddressingMode = new AbsoluteYAddressingMode(); accumulatorAddressingMode = new AccumulatorAddressingMode(); immediateAddressingMode = new ImmediateAddressingMode(); impliedAddressingMode = new ImpliedAddressingMode(); indirectAddressingMode = new IndirectAddressingMode(); indirectXAddressingMode = new IndirectXAddressingMode(); indirectYAddressingMode = new IndirectYAddressingMode(); relativeAddressingMode = new RelativeAddressingMode(); zeroPageAddressingMode = new ZeroPageAddressingMode(); zeroPageXAddressingMode = new ZeroPageXAddressingMode(); zeroPageYAddressingMode = new ZeroPageYAddressingMode(); OpCodeDefinitions.OpCodeList.ForEach(x => { OpCodeHandlers.Add(x.OpCode, new OpCodeHandler { OpCodeDefinition = x, Operation = x.Nemonic switch { OpCode.ADC => adcOperation, OpCode.AND => andOperation, OpCode.ASL => aslOperation, OpCode.BCC => bccOperation, OpCode.BCS => bcsOperation, OpCode.BEQ => beqOperation, OpCode.BIT => bitOperation, OpCode.BMI => bmiOperation, OpCode.BNE => bneOperation, OpCode.BPL => bplOperation, //OpCode.BRK => throw new NotImplementedException(), OpCode.BVC => bvcOperation, OpCode.BVS => bvsOperation, OpCode.CLC => clcOperation, OpCode.CLD => cldOperation, OpCode.CLI => cliOperation, OpCode.CLV => clvOperation, OpCode.CMP => cmpOperation, OpCode.CPX => cpxOperation, OpCode.CPY => cpyOperation, OpCode.DEC => decOperation, OpCode.DEX => dexOperation, OpCode.DEY => deyOperation, OpCode.EOR => eorOperation, OpCode.INC => incOperation, OpCode.INX => inxOperation, OpCode.INY => inyOperation, OpCode.JMP => jmpOperation, OpCode.JSR => jsrOperation, OpCode.LDA => ldaOperation, OpCode.LDX => ldxOperation, OpCode.LDY => ldyOperation, OpCode.LSR => lsrOperation, OpCode.NOP => nopOperation, OpCode.ORA => oraOperation, OpCode.PHA => phaOperation, OpCode.PHP => phpOperation, OpCode.PLA => plaOperation, OpCode.PLP => plpOperation, OpCode.ROL => rolOperation, OpCode.ROR => rorOperation, OpCode.RTI => rtiOperation, OpCode.RTS => rtsOperation, OpCode.SBC => sbcOperation, OpCode.SEC => secOperation, OpCode.SED => sedOperation, OpCode.SEI => seiOperation, OpCode.STA => staOperation, OpCode.STX => stxOperation, OpCode.STY => styOperation, OpCode.TAX => taxOperation, OpCode.TAY => tayOperation, OpCode.TSX => tsxOperation, OpCode.TXA => txaOperation, OpCode.TXS => txsOperation, OpCode.TYA => tyaOperation, OpCode.LAX => laxOperation, _ => nopOperation, }, AddressingMode = x.AddressingMode switch { AddressingMode.NON => noneAddressingMode, AddressingMode.ZP0 => zeroPageAddressingMode, AddressingMode.ZPX => zeroPageXAddressingMode, AddressingMode.ZPY => zeroPageYAddressingMode, AddressingMode.ABS => absoluteAddressingMode, AddressingMode.ABX => absoluteXAddressingMode, AddressingMode.ABY => absoluteYAddressingMode, AddressingMode.IND => indirectAddressingMode, AddressingMode.IDX => indirectXAddressingMode, AddressingMode.IDY => indirectYAddressingMode, AddressingMode.IMP => impliedAddressingMode, AddressingMode.ACC => accumulatorAddressingMode, AddressingMode.IMM => immediateAddressingMode, AddressingMode.REL => relativeAddressingMode, _ => throw new NotImplementedException(), } });
protected abstract void Generate(OpCodeHandlers handlers);
protected override void Generate(OpCodeHandlers handlers) { GenerateOpCodeOperandKindTables(handlers); GenerateOpTables(handlers); }