public Expression BuildInstructionSpaceExpression(IEnumerable<InstructionInfo> instructions, IProgramControlExpressionLibrary programControlExpressionLibrary, IInstructionExpressionBuilder instructionBuilder, InstructionSpace instructionSpace) { if (instructionSpace.Prefix == null) return BuildSwitch(instructions, programControlExpressionLibrary, instructionBuilder, String.Empty); else return BuildSwitch(instructions, programControlExpressionLibrary, instructionBuilder, instructionSpace.Prefix); }
public Expression BuildInstructionSpaceExpression(IEnumerable<InstructionInfo> instructions, IProgramControlExpressionLibrary programControlExpressionLibrary, IInstructionExpressionBuilder instructionBuilder, InstructionSpace instructionSpace) { List<SwitchCase> switchCases = new List<SwitchCase>(); foreach (var info in instructions) { if (String.IsNullOrEmpty(info.Prefix)) continue; if (info.Prefix.StartsWith(instructionSpace.Prefix)) { switchCases.Add( Expression.SwitchCase(instructionBuilder.BuildExpression(info), Expression.Constant(info.Opcode)) ); } } return Expression.Block( // Read index parameter. // index - (index & 0x80) << 1 - Handles negative indexes. Expression.Assign(programControlExpressionLibrary.ParameterByte2, programControlExpressionLibrary.ReadAndIncrementProgramCounter), Expression.Assign(programControlExpressionLibrary.ParameterByte1, Expression.Subtract( programControlExpressionLibrary.ParameterByte2, Expression.LeftShift( Expression.And(programControlExpressionLibrary.ParameterByte2, Expression.Constant(0x80)), Expression.Constant(0x01) ) ) ), Expression.Switch(programControlExpressionLibrary.ReadAndIncrementProgramCounter, Expression.Assign(programControlExpressionLibrary.ParameterByte1, programControlExpressionLibrary.ParameterByte1), switchCases.ToArray()) ); }
private SwitchExpression BuildSwitch(IEnumerable<InstructionInfo> instructions, IProgramControlExpressionLibrary programControlExpressionLibrary, IInstructionExpressionBuilder instructionBuilder, String prefix) { List<SwitchCase> switchCases = new List<SwitchCase>(); // Build switch cases for instruction within this prefix space. foreach (var info in instructions) { if ((String.IsNullOrEmpty(prefix) && String.IsNullOrEmpty(info.Prefix)) || info.Prefix == prefix) { try { switchCases.Add( Expression.SwitchCase( instructionBuilder.BuildExpression(info), Expression.Constant(info.Opcode) ) ); } catch (Exception ex) { throw new ApplicationException(String.Format("There was an error trying to build the instruction expression for {0}", info.Mnemonic), ex); } } } // Build switch cases for child instruction spaces. foreach (var prefixOpcode in FindPrefixOpcodes(prefix, instructions)) { IInstructionSpaceBuilder instructionSpace; if ((prefix + prefixOpcode.ToString("X")) == "DDCB" || (prefix + prefixOpcode.ToString("X")) == "FDCB") { instructionSpace = new CBInstructionSpaceBuilder(); } else { instructionSpace = new DefaultInstructionSpaceBuilder(); } switchCases.Add( Expression.SwitchCase( instructionSpace.BuildInstructionSpaceExpression(instructions, programControlExpressionLibrary, instructionBuilder, new InstructionSpace(prefix + prefixOpcode.ToString("X"))), Expression.Constant(prefixOpcode) ) ); } var orderedSwitchCases = switchCases.OrderBy(sc => (Int32)((ConstantExpression)(sc.TestValues.First())).Value); return Expression.Switch(programControlExpressionLibrary.ReadAndIncrementProgramCounter, Expression.Block( Expression.Throw(Expression.New(_unknownInstruction, Expression.Subtract(programControlExpressionLibrary.ProgramCounterRegister, Expression.Constant(1)))), Expression.Assign(programControlExpressionLibrary.ParameterByte1, programControlExpressionLibrary.ParameterByte1) ), orderedSwitchCases.ToArray() ); }