public IXILMapping TryAllocate(Component host, XILInstr instr, TypeDescriptor[] operandTypes, TypeDescriptor[] resultTypes, IProject targetProject) { if (operandTypes.Length != 1 || resultTypes.Length != 2) { return(null); } if (!operandTypes[0].CILType.Equals(typeof(SFix)) || !resultTypes[0].CILType.Equals(typeof(SFix)) || !resultTypes[1].Equals(resultTypes[0])) { return(null); } var xfmt = SFix.GetFormat(operandTypes[0]); var yfmt = SFix.GetFormat(resultTypes[0]); int lutWidth = Math.Max(1, xfmt.FracWidth - 1); int mulWidth = Math.Max(1, xfmt.FracWidth - lutWidth); int pipeStages = 0; // 2 * mulWidth * mulWidth / (18 * 18) + yfmt.FracWidth / 18 + 1; var scc = new SinCosLUTCore(lutWidth, xfmt.FracWidth, yfmt.FracWidth, pipeStages); var mappings = TryMap(scc.TASite, instr, operandTypes, resultTypes); Debug.Assert(mappings.Any()); return(mappings.First()); }
public IEnumerable <IXILMapping> TryMap(ITransactionSite taSite, XILInstr instr, TypeDescriptor[] operandTypes, TypeDescriptor[] resultTypes) { if (!instr.Name.Equals(InstructionCodes.RdPort)) { yield break; } var ts = taSite as DirectPortReadTransactionSite; if (ts == null) { yield break; } //if (ts.Host != _host) // yield break; var tgPort = (ISignalOrPortDescriptor)instr.Operand; if (!ts.Port.Equals(tgPort)) { yield break; } yield return(new DirectPortReadXILMapping(ts.Host, ts)); }
private bool TryGetConstSLV(XILInstr instr, TypeDescriptor rtype, out StdLogicVector constSLV) { switch (instr.Name) { case InstructionCodes.LdConst: { object constValue = instr.Operand; constSLV = StdLogicVector.Serialize(constValue); } break; case InstructionCodes.Ld0: { object sample = rtype.GetSampleInstance(); StdLogicVector slv = StdLogicVector.Serialize(sample); constSLV = StdLogicVector._0s(slv.Size); } break; default: { constSLV = ""; return(false); } } return(true); }
public IEnumerable <IXILMapping> TryMap(ITransactionSite taSite, XILInstr instr, TypeDescriptor[] operandTypes, TypeDescriptor[] resultTypes) { var fu = taSite.Host; Slicer slicer = fu as Slicer; if (slicer == null) { yield break; } bool isSigned; int inputWidth, hiOffset, loOffset; if (!GetSliceParams(instr, operandTypes, resultTypes, out isSigned, out inputWidth, out hiOffset, out loOffset)) { yield break; } if (slicer.IsSigned != isSigned) { yield break; } if (slicer.InputWidth != inputWidth) { yield break; } if (hiOffset != slicer.HiOffset || loOffset != slicer.LoOffset) { yield break; } yield return(new SlicerXILMapping(slicer)); }
public IEnumerable <IXILMapping> TryMap(ITransactionSite taSite, XILInstr instr, TypeDescriptor[] operandTypes, TypeDescriptor[] resultTypes) { var fu = taSite.Host; //if (fu != _host) // yield break; var taBM = taSite as InlineBCUTransactionSite; if (taBM == null) { yield break; } switch (instr.Name) { case InstructionCodes.Goto: yield return(new InlineBCUMapping(taBM, InstructionCodes.Goto, (BranchLabel)instr.Operand)); break; case InstructionCodes.BranchIfTrue: yield return(new InlineBCUMapping(taBM, InstructionCodes.BranchIfTrue, (BranchLabel)instr.Operand)); break; case InstructionCodes.BranchIfFalse: yield return(new InlineBCUMapping(taBM, InstructionCodes.BranchIfFalse, (BranchLabel)instr.Operand)); break; default: yield break; } }
private void Process(XIL3Instr xil3i) { var preds = xil3i.Preds.Select(p => p.Remap(_slotRemap[p.PredIndex])).ToArray(); _instRemap.Add(_outInstrs.Count); foreach (int oslot in xil3i.OperandSlots) { Emit(DefaultInstructionSet.Instance .LoadVar(_interLocals[oslot]).CreateStk(preds, 0, _interLocals[oslot].Type)); } _slotRemap.Add(_outInstrs.Count); var cmd = xil3i.Command; if (cmd.Name == InstructionCodes.BranchIfFalse || cmd.Name == InstructionCodes.BranchIfTrue || cmd.Name == InstructionCodes.Goto) { var target = (BranchLabel)cmd.Operand; var newTarget = new BranchLabel() { InstructionIndex = target.InstructionIndex }; cmd = new XILInstr(cmd.Name, newTarget) { BackRef = cmd.BackRef }; _labels.Add(newTarget); } Emit(cmd.CreateStk(preds, xil3i.OperandSlots.Length, xil3i.OperandSlots.Select(os => _interLocals[os].Type) .Concat(xil3i.ResultSlots.Select(rs => _interLocals[rs].Type)) .ToArray())); foreach (int rslot in xil3i.ResultSlots.Reverse()) { Emit(DefaultInstructionSet.Instance .StoreVar(_interLocals[rslot]).CreateStk(1, _interLocals[rslot].Type)); } }
public IXILMapping TryAllocate(Component host, XILInstr instr, TypeDescriptor[] operandTypes, TypeDescriptor[] resultTypes, IProject targetProject) { if (instr.Name != InstructionCodes.Abs) { return(null); } var operandFormat = operandTypes[0].GetFixFormat(); if (operandFormat == null) { return(null); } var resultFormat = resultTypes[0].GetFixFormat(); if (resultFormat == null) { return(null); } if (operandFormat.FracWidth != resultFormat.FracWidth) { return(null); } var fu = new FixedAbs( operandFormat.TotalWidth, resultFormat.TotalWidth, ComputeLatency(operandFormat.TotalWidth, resultFormat.TotalWidth)); return(new AbsMapping(fu)); }
public IEnumerable <IXILMapping> TryMap(ITransactionSite taSite, XILInstr instr, TypeDescriptor[] operandTypes, TypeDescriptor[] resultTypes) { var fu = taSite.Host; var scc = fu as SinCosLUTCore; if (scc == null) { yield break; } if (operandTypes.Length != 1 || resultTypes.Length != 2) { yield break; } var xType = TypeDescriptor.GetTypeOf(SFix.FromDouble(0.0, scc.XIntWidth, scc.XFracWidth)); var yType = TypeDescriptor.GetTypeOf(SFix.FromDouble(0.0, scc.YIntWidth, scc.YFracWidth)); if (!operandTypes[0].Equals(xType) || !resultTypes[0].Equals(yType) || !resultTypes[1].Equals(yType)) { yield break; } if (instr.Name != InstructionCodes.ScSinCos) { yield break; } yield return(new Mapping(scc)); }
public IXILMapping TryAllocate(Component host, XILInstr instr, TypeDescriptor[] operandTypes, TypeDescriptor[] resultTypes, IProject targetProject) { var far = instr.Operand as FixedArrayRef; if (far == null) { return(null); } var taSite = new MemoryMapperTransactionSite(this, host, far); switch (instr.Name) { case InstructionCodes.LdelemFixA: return(new LdelemFixAMapping(taSite)); case InstructionCodes.LdelemFixAFixI: return(new LdelemFixAFixIMapping(taSite, far.Indices)); case InstructionCodes.StelemFixA: return(new StelemFixAMapping(taSite)); case InstructionCodes.StelemFixAFixI: return(new StelemFixAFixIMapping(taSite, far.Indices)); default: return(null); } }
public IEnumerable <IXILMapping> TryMap(ITransactionSite taSite, XILInstr instr, TypeDescriptor[] operandTypes, TypeDescriptor[] resultTypes) { var mapping = TryMapOne(taSite, instr, operandTypes, resultTypes); if (mapping != null) { yield return(mapping); } }
/// <summary> /// The default branch handler is applied to any branching instruction when there is no more specific handler registered. /// </summary> /// <param name="i">instruction to process</param> virtual protected void ProcessBranch(XILSInstr i) { BranchLabel label = (BranchLabel)i.StaticOperand; BranchLabel newLabel = Retarget(label); XILInstr xi = new XILInstr(i.Name, newLabel); var preds = RemapPreds(i.Preds); Emit(xi.CreateStk(preds, i.OperandTypes, i.ResultTypes)); }
public IEnumerable <IXILMapping> TryMap(ITransactionSite taSite, XILInstr instr, TypeDescriptor[] operandTypes, TypeDescriptor[] resultTypes) { var fu = taSite.Host; FixFPMod1 fpmod1 = fu as FixFPMod1; if (fpmod1 == null) { yield break; } if (instr.Name != InstructionCodes.Mod2 && instr.Name != InstructionCodes.Rempow2) { yield break; } if (instr.Name == InstructionCodes.Rempow2) { int n = (int)instr.Operand; if (n != 0) { yield break; } } FixFormat infmt = GetFixFormat(operandTypes[0]); FixFormat outfmt = GetFixFormat(resultTypes[0]); if (infmt == null || outfmt == null) { yield break; } if (infmt.IntWidth < 2 || outfmt.IntWidth < 2) { yield break; } if (infmt.FracWidth != outfmt.FracWidth) { yield break; } if (infmt.IntWidth != fpmod1.InIntWidth) { yield break; } if (infmt.FracWidth != fpmod1.FracWidth) { yield break; } if (outfmt.IntWidth != fpmod1.OutIntWidth) { yield break; } yield return(new FPMod1XILMapping(fpmod1)); }
public IEnumerable <IXILMapping> TryMap(ITransactionSite taSite, XILInstr instr, TypeDescriptor[] operandTypes, TypeDescriptor[] resultTypes) { var fu = taSite.Host; var fna = fu as FloatNegAbs; if (fna == null) { yield break; } if (operandTypes.Length != 1 || resultTypes.Length != 1) { yield break; } int totalWidth; if (operandTypes[0].CILType.Equals(typeof(float)) && resultTypes[0].CILType.Equals(typeof(float))) { totalWidth = 32; } else if (operandTypes[0].CILType.Equals(typeof(double)) && resultTypes[0].CILType.Equals(typeof(double))) { totalWidth = 64; } else { yield break; } if (fna.TotalWidth != totalWidth) { yield break; } switch (fna.Operation) { case FloatNegAbs.EOperation.Abs: if (instr.Name != InstructionCodes.Abs) { yield break; } break; case FloatNegAbs.EOperation.Neg: if (instr.Name != InstructionCodes.Neg) { yield break; } break; default: throw new NotImplementedException(); } yield return(new Mapping(fna)); }
/// <summary> /// Constructs a <c>FunctionCall</c> representation of executing a XIL instruction. /// </summary> /// <param name="xi">XIL instruction to execute</param> /// <param name="resultType">result type descriptor</param> /// <param name="args">expressions representing the instruction arguments</param> public static FunctionCall XILOpCode(XILInstr xi, TypeDescriptor resultType, params Expression[] args) { return(new FunctionCall() { Callee = MakeFun( new IntrinsicFunction(IntrinsicFunction.EAction.XILOpCode, xi), resultType), Arguments = args, ResultType = resultType }); }
public IEnumerable <IXILMapping> TryMap(ITransactionSite taSite, XILInstr instr, TypeDescriptor[] operandTypes, TypeDescriptor[] resultTypes) { var fu = taSite.Host; var fsas = fu as FloatSignAsSigned; if (fsas == null) { yield break; } if (instr.Name != InstructionCodes.Sign) { yield break; } int floatWidth; if (operandTypes[0].CILType.Equals(typeof(float))) { floatWidth = 32; } else if (operandTypes[0].CILType.Equals(typeof(double))) { floatWidth = 64; } else if (operandTypes[0].CILType.Equals(typeof(Signed)) || operandTypes[0].CILType.Equals(typeof(SFix))) { floatWidth = operandTypes[0].GetFixFormat().TotalWidth; } else { yield break; } if (floatWidth != fsas.FloatWidth) { yield break; } var fmt = resultTypes[0].GetFixFormat(); if (fmt == null || !fmt.IsSigned || fmt.IntWidth < 2) { yield break; } if (!fmt.Equals(fsas.OutFormat)) { yield break; } yield return(new Mapping(fsas)); }
/// <summary> /// The default branch handler is applied to any branching instruction when there is no more specific handler registered. /// </summary> /// <param name="i">instruction to process</param> virtual protected void ProcessBranch(XIL3Instr i) { BranchLabel label = (BranchLabel)i.StaticOperand; BranchLabel newLabel = Retarget(label); XILInstr xi = new XILInstr(i.Name, newLabel); int[] rslots = RemapResultSlots(i.ResultSlots); int[] oslots = RemapOperandSlots(i.OperandSlots); var preds = RemapPreds(i.Preds); Emit(xi.Create3AC(preds, oslots, rslots)); }
public IXILMapping TryAllocate(Component host, XILInstr instr, TypeDescriptor[] operandTypes, TypeDescriptor[] resultTypes, IProject proj) { if (instr.Name != InstructionCodes.Select) { return(null); } int width = TypeLowering.Instance.GetWireWidth(operandTypes[1]); MUX2 mux2 = new MUX2(width); return(new MUX2XILMapping(mux2.TASite)); }
public IEnumerable <IXILMapping> TryMap(ITransactionSite taSite, XILInstr instr, TypeDescriptor[] operandTypes, TypeDescriptor[] resultTypes) { var fu = taSite.Host; Shifter shifter = fu as Shifter; if (shifter == null) { yield break; } if (instr.Name != InstructionCodes.LShift && instr.Name != InstructionCodes.RShift) { yield break; } int fmtData = GetFixSize(operandTypes[0]); int fmtShift = GetFixSize(operandTypes[1]); int fmtResult = GetFixSize(resultTypes[0]); if (fmtData < 0 || fmtShift < 0 || fmtResult < 0) { yield break; } if (fmtData != fmtResult) { yield break; } if (shifter.DataWidth != fmtData || shifter.ShiftWidth != fmtShift) { yield break; } switch (instr.Name) { case InstructionCodes.LShift: yield return(new LShiftXILMapping(shifter)); break; case InstructionCodes.RShift: yield return(new RShiftXILMapping(shifter)); break; default: throw new NotImplementedException(); } }
public IXILMapping TryMapOne(ITransactionSite taSite, XILInstr instr, TypeDescriptor[] operandTypes, TypeDescriptor[] resultTypes, bool swap) { var fu = taSite.Host; var asub = fu as XilinxAdderSubtracter; if (asub == null) { return(null); } bool iisAdd = instr.Name == InstructionCodes.Add; bool iisSub = instr.Name == InstructionCodes.Sub; if ((asub.AddMode == XilinxAdderSubtracter.EAddMode.Add && !iisAdd) || (asub.AddMode == XilinxAdderSubtracter.EAddMode.Subtract && !iisSub) || (!iisAdd && !iisSub)) { return(null); } FixFormat fmta, fmtb, fmtr; fmta = GetFixFormat(operandTypes[0]); fmtb = GetFixFormat(operandTypes[1]); fmtr = GetFixFormat(resultTypes[0]); if (fmta == null || fmtb == null || fmtr == null) { return(null); } bool expectSigned = fmta.IsSigned || fmtb.IsSigned; if (expectSigned != fmtr.IsSigned) { return(null); } if (fmta.FracWidth != fmtb.FracWidth || fmtr.FracWidth != fmta.FracWidth) { return(null); } if (fmta.TotalWidth != asub.Awidth || fmtb.TotalWidth != asub.Bwidth || fmtr.TotalWidth != asub.OutWidth) { return(null); } return(new XILMapping(asub, iisAdd, swap)); }
public IXILMapping TryAllocate(Component host, XILInstr instr, TypeDescriptor[] operandTypes, TypeDescriptor[] resultTypes, IProject proj) { switch (instr.Name) { case InstructionCodes.Goto: case InstructionCodes.BranchIfTrue: case InstructionCodes.BranchIfFalse: return(TryMap(new InlineBCUTransactionSite(this, host), instr, operandTypes, resultTypes).SingleOrDefault()); default: return(null); } }
public IXILMapping TryAllocate(Component host, XILInstr instr, TypeDescriptor[] operandTypes, TypeDescriptor[] resultTypes, IProject targetProject) { switch (instr.Name) { case InstructionCodes.Goto: case InstructionCodes.BranchIfTrue: case InstructionCodes.BranchIfFalse: return(TryMap(_host.TASite, instr, operandTypes, resultTypes).Single()); default: return(null); } }
public IXILMapping TryAllocate(Component host, XILInstr instr, TypeDescriptor[] operandTypes, TypeDescriptor[] resultTypes, IProject proj) { List<IXILMapper> mappers = _mlookup.Get(instr.Name); foreach (IXILMapper mapper in mappers) { IXILMapping mapping = mapper.TryAllocate(host, instr, operandTypes, resultTypes, proj); if (mapping != null) { return mapping; } } return null; }
public IXILMapping TryAllocate(Component host, XILInstr instr, TypeDescriptor[] operandTypes, TypeDescriptor[] resultTypes, IProject proj) { StdLogicVector constSLV; if (!TryGetConstSLV(instr, resultTypes[0], out constSLV)) { return(null); } var clts = new ConstLoadingTransactionSite(host, constSLV, CreateSignalsForConstants); return(new ConstLoadingXILMapping(clts)); }
public IEnumerable <IXILMapping> TryMap(ITransactionSite taSite, XILInstr instr, TypeDescriptor[] operandTypes, TypeDescriptor[] resultTypes) { var fu = taSite.Host; //if (fu != _host) // yield break; var taNop = taSite as NopTASite; if (taNop == null) { yield break; } switch (instr.Name) { case InstructionCodes.Nop: case InstructionCodes.Barrier: if (instr.Operand is int) { yield return(new NopXILMapping(taNop, (int)instr.Operand)); } else { yield return(new NopXILMapping(taNop, 0)); } break; case InstructionCodes.Convert: if (TypeLowering.Instance.HasWireType(operandTypes[0]) && TypeLowering.Instance.HasWireType(resultTypes[0]) && !operandTypes[0].CILType.Equals(resultTypes[0].CILType)) { TypeDescriptor owt = TypeLowering.Instance.GetWireType(operandTypes[0]); TypeDescriptor rwt = TypeLowering.Instance.GetWireType(resultTypes[0]); if (!owt.Equals(rwt)) { yield break; } yield return(new IdXILMapping(taNop)); } else { yield break; } break; default: yield break; } }
public IXILMapping TryAllocate(Component host, XILInstr instr, TypeDescriptor[] operandTypes, TypeDescriptor[] resultTypes, IProject proj) { if (!instr.Name.Equals(InstructionCodes.WrPort)) { return(null); } var tgPort = (ISignalOrPortDescriptor)instr.Operand; InlinePortWriteSite taSite; taSite = new InlinePortWriteSite(host, tgPort); return(new InlinePortWriterXILMapping(taSite)); }
public IEnumerable <IXILMapping> TryMap(ITransactionSite taSite, XILInstr instr, TypeDescriptor[] operandTypes, TypeDescriptor[] resultTypes) { StdLogicVector constSLV; if (!TryGetConstSLV(instr, resultTypes[0], out constSLV)) { yield break; } var fu = taSite.Host; ConstLoadingTransactionSite clts = new ConstLoadingTransactionSite(fu, constSLV, CreateSignalsForConstants); yield return(new ConstLoadingXILMapping(clts)); }
public IXILMapping TryMapOne(ITransactionSite taSite, XILInstr instr, TypeDescriptor[] operandTypes, TypeDescriptor[] resultTypes, bool swap) { var fu = taSite.Host; XilinxMultiplier mul = fu as XilinxMultiplier; if (mul == null) { return(null); } if (instr.Name != InstructionCodes.Mul) { return(null); } if (mul.MultType != XilinxMultiplier.EMultiplierType.ParallelMultiplier) { return(null); } FixFormat fmta, fmtb, fmtr; fmta = GetFixFormat(operandTypes[0]); fmtb = GetFixFormat(operandTypes[1]); fmtr = GetFixFormat(resultTypes[0]); if (fmta == null || fmtb == null || fmtr == null) { return(null); } bool expectSigned = fmta.IsSigned || fmtb.IsSigned; if (expectSigned != fmtr.IsSigned) { return(null); } int expectedHigh = fmtr.IntWidth + fmta.FracWidth + fmtb.FracWidth - 1; int expectedLow = fmta.FracWidth + fmtb.FracWidth - fmtr.FracWidth; if (fmta.TotalWidth != mul.PortAWidth || fmtb.TotalWidth != mul.PortBWidth || expectedHigh != mul.OutputWidthHigh || expectedLow != mul.OutputWidthLow) { return(null); } return(new XILMapping(mul, swap)); }
public IEnumerable <IXILMapping> TryMap(ITransactionSite taSite, XILInstr instr, TypeDescriptor[] operandTypes, TypeDescriptor[] resultTypes) { var alt0 = TryMapOne(taSite, instr, operandTypes, resultTypes, false); var alt1 = TryMapOne(taSite, instr, new TypeDescriptor[] { operandTypes[1], operandTypes[0] }, resultTypes, true); if (alt0 != null) { yield return(alt0); } if (alt1 != null) { yield return(alt1); } }
public IXILMapping TryAllocate(Component host, XILInstr instr, TypeDescriptor[] operandTypes, TypeDescriptor[] resultTypes, IProject targetProject) { if (instr.Name != InstructionCodes.Concat) { return(null); } int[] inWidths = operandTypes.Select(t => Marshal.SerializeForHW(t.GetSampleInstance()).Size).ToArray(); var key = new KeyClass(inWidths); InlineConcatMapperTransactionSite taSite = new InlineConcatMapperTransactionSite(this, host, inWidths); return(new ConcatMapping(taSite)); }
protected override void ProcessDefault(XILSInstr i) { XILInstr cmd = i.Command; if (cmd.Name.Equals(InstructionCodes.LdConst)) { object value = cmd.Operand; object lvalue = TypeLowering.Instance.ConvertToHardwareType(value); cmd = DefaultInstructionSet.Instance.LdConst(lvalue); } base.ProcessDefault( cmd.CreateStk( i.Preds, ReduceTypes(i.OperandTypes), ReduceTypes(i.ResultTypes))); }
public IEnumerable <IXILMapping> TryMap(ITransactionSite taSite, XILInstr instr, TypeDescriptor[] operandTypes, TypeDescriptor[] resultTypes) { var fu = taSite.Host; var far = instr.Operand as FixedArrayRef; if (far == null) { yield break; } var taMM = taSite as MemoryMapperTransactionSite; if (taMM == null) { yield break; } if (taMM.Array.ArrayObj != far.ArrayObj) { yield break; } switch (instr.Name) { case InstructionCodes.LdelemFixA: yield return(new LdelemFixAMapping(taMM)); break; case InstructionCodes.LdelemFixAFixI: yield return(new LdelemFixAFixIMapping(taMM, far.Indices)); break; case InstructionCodes.StelemFixA: yield return(new StelemFixAMapping(taMM)); break; case InstructionCodes.StelemFixAFixI: yield return(new StelemFixAFixIMapping(taMM, far.Indices)); break; default: yield break; } }
public IEnumerable <IXILMapping> TryMap(ITransactionSite taSite, XILInstr instr, TypeDescriptor[] operandTypes, TypeDescriptor[] resultTypes) { IFixedAbsTransactionSite fats = taSite as IFixedAbsTransactionSite; if (fats == null) { yield break; } if (instr.Name != InstructionCodes.Abs) { yield break; } var operandFormat = operandTypes[0].GetFixFormat(); if (operandFormat == null) { yield break; } var resultFormat = resultTypes[0].GetFixFormat(); if (resultFormat == null) { yield break; } if (operandFormat.FracWidth != resultFormat.FracWidth) { yield break; } if (operandFormat.TotalWidth != fats.Host.InputWidth) { yield break; } if (resultFormat.TotalWidth != fats.Host.OutputWidth) { yield break; } yield return(new AbsMapping(fats.Host)); }
private bool GetSliceParams(XILInstr instr, TypeDescriptor[] operandTypes, TypeDescriptor[] resultTypes, out bool isSigned, out int inputWidth, out int hiOffset, out int loOffset) { isSigned = false; inputWidth = 0; hiOffset = 0; loOffset = 0; if (instr.Name != InstructionCodes.Convert && instr.Name != InstructionCodes.SliceFixI && instr.Name != InstructionCodes.Rempow2) return false; bool o0fix = IsSigned(operandTypes[0]) || IsUnsigned(operandTypes[0]); bool r0fix = IsSigned(resultTypes[0]) || IsUnsigned(resultTypes[0]); bool u2s = o0fix && r0fix; bool typesEq = operandTypes[0].CILType.Equals(resultTypes[0].CILType); if (!u2s && !typesEq) return false; if (!IsSliceable(operandTypes[0]) || !IsSliceable(resultTypes[0])) return false; isSigned = IsSigned(operandTypes[0]) && IsSigned(resultTypes[0]); inputWidth = TypeLowering.Instance.GetWireWidth(operandTypes[0]); switch (instr.Name) { case InstructionCodes.Convert: { TypeDescriptor inWType = operandTypes[0]; TypeDescriptor outWType = resultTypes[0]; hiOffset = outWType.Constraints[0].FirstBound - inWType.Constraints[0].SecondBound; loOffset = outWType.Constraints[0].SecondBound - inWType.Constraints[0].SecondBound; } break; case InstructionCodes.SliceFixI: { Range range = (Range)instr.Operand; hiOffset = range.FirstBound; loOffset = range.SecondBound; } break; case InstructionCodes.Rempow2: { if (!IsSigned(operandTypes[0]) || !IsSigned(resultTypes[0])) return false; var infmt = operandTypes[0].GetFixFormat(); int p2 = (int)instr.Operand; if (infmt.IntWidth > p2 + 1) return false; goto case InstructionCodes.Convert; } default: throw new NotImplementedException(); } return true; }
public IXILMapping TryAllocate(Component host, XILInstr instr, TypeDescriptor[] operandTypes, TypeDescriptor[] resultTypes, IProject proj) { bool iisAdd = instr.Name == InstructionCodes.Add; bool iisSub = instr.Name == InstructionCodes.Sub; if (!iisAdd && !iisSub) return null; FixFormat fmta, fmtb, fmtr; fmta = GetFixFormat(operandTypes[0]); fmtb = GetFixFormat(operandTypes[1]); fmtr = GetFixFormat(resultTypes[0]); if (fmta == null || fmtb == null || fmtr == null) return null; bool expectSigned = fmta.IsSigned || fmtb.IsSigned; if (expectSigned != fmtr.IsSigned) return null; if (fmta.FracWidth != fmtb.FracWidth || fmtr.FracWidth != fmta.FracWidth) return null; int expectedWidth = Math.Max(fmta.TotalWidth, fmtb.TotalWidth); if (fmtr.TotalWidth != expectedWidth && fmtr.TotalWidth != (expectedWidth + 1)) return null; var xproj = proj as XilinxProject; if (xproj == null) return null; var asub = new XilinxAdderSubtracter() { AddMode = iisAdd ? XilinxAdderSubtracter.EAddMode.Add : XilinxAdderSubtracter.EAddMode.Subtract, Atype = fmta.IsSigned ? XilinxAdderSubtracter.ESignedness.Signed : XilinxAdderSubtracter.ESignedness.Unsigned, Awidth = fmta.TotalWidth, Bconstant = false, Btype = fmtb.IsSigned ? XilinxAdderSubtracter.ESignedness.Signed : XilinxAdderSubtracter.ESignedness.Unsigned, Bwidth = fmtb.TotalWidth, Implementation = XilinxAdderSubtracter.EImplementation.Fabric, TargetDeviceFamily = xproj.DeviceFamily, OutWidth = fmtr.TotalWidth, LatencyConfiguration = XilinxAdderSubtracter.ELatencyConfiguration.Automatic }; int scaledStages = (int)Math.Round(Config.PipeStageScaling * asub.Latency); asub.LatencyConfiguration = XilinxAdderSubtracter.ELatencyConfiguration.Manual; asub.Latency = scaledStages; return new XILMapping(asub, iisAdd, false); }
public IXILMapping TryAllocate(Component host, XILInstr instr, TypeDescriptor[] operandTypes, TypeDescriptor[] resultTypes, IProject proj) { if (instr.Name != InstructionCodes.Concat) return null; if (!operandTypes[0].CILType.Equals(typeof(StdLogicVector)) || !resultTypes[0].CILType.Equals(typeof(StdLogicVector))) return null; if (!operandTypes.All(t => t.Equals(operandTypes[0]))) return null; int wordWidth = (int)operandTypes[0].TypeParams[0]; Concatenizer cc = new Concatenizer(operandTypes.Length, wordWidth); return new ConcatXILMapping(cc); }
private bool CheckFixCompliance(XILInstr instr, TypeDescriptor[] operandTypes, TypeDescriptor[] resultTypes) { var oldMode = DesignContext.Instance.FixPoint.ArithSizingMode; DesignContext.Instance.FixPoint.ArithSizingMode = EArithSizingMode.VHDLCompliant; bool result = CheckFixComplianceInternal(instr, operandTypes, resultTypes); DesignContext.Instance.FixPoint.ArithSizingMode = oldMode; return result; }
/// <summary> /// Constructs a <c>FunctionCall</c> representation of executing a XIL instruction. /// </summary> /// <param name="xi">XIL instruction to execute</param> /// <param name="resultType">result type descriptor</param> /// <param name="args">expressions representing the instruction arguments</param> public static FunctionCall XILOpCode(XILInstr xi, TypeDescriptor resultType, params Expression[] args) { return new FunctionCall() { Callee = MakeFun( new IntrinsicFunction(IntrinsicFunction.EAction.XILOpCode, xi), resultType), Arguments = args, ResultType = resultType }; }
public IXILMapping TryMapOne(ITransactionSite taSite, XILInstr instr, TypeDescriptor[] operandTypes, TypeDescriptor[] resultTypes) { var fu = taSite.Host; XilinxDivider divider = fu as XilinxDivider; if (divider == null) return null; if (instr.Name != InstructionCodes.Div && instr.Name != InstructionCodes.DivQF) return null; FixFormat fmtDividend = GetFixFormat(operandTypes[0]); FixFormat fmtDivisor = GetFixFormat(operandTypes[1]); FixFormat fmtQuotient = GetFixFormat(resultTypes[0]); FixFormat fmtFractional = null; if (instr.Name == InstructionCodes.DivQF) fmtFractional = GetFixFormat(resultTypes[1]); if (fmtDividend.IsSigned != fmtDivisor.IsSigned || fmtDividend.IsSigned != fmtQuotient.IsSigned) return null; if (fmtDividend.TotalWidth != fmtQuotient.TotalWidth) return null; int qFracWidth = fmtDividend.FracWidth - fmtDivisor.FracWidth; if (qFracWidth != fmtQuotient.FracWidth) return null; int fracWidth = 0; if (fmtFractional != null) fracWidth = fmtFractional.TotalWidth; if (divider.DividendAndQuotientWidth != fmtDividend.TotalWidth) return null; if (divider.DivisorWidth != fmtDivisor.TotalWidth) return null; if ((divider.OperandSign == XilinxDivider.ESignedness.Signed) != fmtDividend.IsSigned) return null; if (divider.FractionWidth != fracWidth) return null; return new DividerXILMapping(divider); }
public IEnumerable<IXILMapping> TryMap(ITransactionSite taSite, XILInstr instr, TypeDescriptor[] operandTypes, TypeDescriptor[] resultTypes) { var mapping = TryMapOne(taSite, instr, operandTypes, resultTypes); if (mapping != null) yield return mapping; }
public IEnumerable<IXILMapping> TryMap(ITransactionSite taSite, XILInstr instr, TypeDescriptor[] operandTypes, TypeDescriptor[] resultTypes) { var fu = taSite.Host; //if (fu != _host) // yield break; var taNop = taSite as NopTASite; if (taNop == null) yield break; switch (instr.Name) { case InstructionCodes.Nop: case InstructionCodes.Barrier: if (instr.Operand is int) yield return new NopXILMapping(taNop, (int)instr.Operand); else yield return new NopXILMapping(taNop, 0); break; case InstructionCodes.Convert: if (TypeLowering.Instance.HasWireType(operandTypes[0]) && TypeLowering.Instance.HasWireType(resultTypes[0]) && !operandTypes[0].CILType.Equals(resultTypes[0].CILType)) { TypeDescriptor owt = TypeLowering.Instance.GetWireType(operandTypes[0]); TypeDescriptor rwt = TypeLowering.Instance.GetWireType(resultTypes[0]); if (!owt.Equals(rwt)) yield break; yield return new IdXILMapping(taNop); } else { yield break; } break; default: yield break; } }
public IXILMapping TryAllocate(Component host, XILInstr instr, TypeDescriptor[] operandTypes, TypeDescriptor[] resultTypes, IProject proj) { if (!CheckFixCompliance(instr, operandTypes, resultTypes)) return null; bool isArith = false; int osize0, osize1 = 0; int rsize; ALU.EArithMode amode; ALU.EFunction op; switch (instr.Name) { case InstructionCodes.Add: case InstructionCodes.Sub: case InstructionCodes.Mul: isArith = true; goto case InstructionCodes.IsLt; case InstructionCodes.IsLt: case InstructionCodes.IsLte: case InstructionCodes.IsEq: case InstructionCodes.IsNEq: case InstructionCodes.IsGte: case InstructionCodes.IsGt: { if (operandTypes.All(t => t.CILType.Equals(typeof(Signed))) && (!isArith || resultTypes[0].CILType.Equals(typeof(Signed))) && (isArith || resultTypes[0].CILType.Equals(typeof(bool)) || resultTypes[0].CILType.Equals(typeof(StdLogicVector)))) amode = ALU.EArithMode.Signed; else if (operandTypes.All(t => t.CILType.Equals(typeof(SFix))) && (!isArith || resultTypes[0].CILType.Equals(typeof(SFix))) && (isArith || resultTypes[0].CILType.Equals(typeof(bool)) || resultTypes[0].CILType.Equals(typeof(StdLogicVector)))) amode = ALU.EArithMode.Signed; else if (operandTypes.All(t => t.CILType.Equals(typeof(Unsigned))) && (!isArith || resultTypes[0].CILType.Equals(typeof(Unsigned))) && (isArith || resultTypes[0].CILType.Equals(typeof(bool)) || resultTypes[0].CILType.Equals(typeof(StdLogicVector)))) amode = ALU.EArithMode.Unsigned; else if (operandTypes.All(t => t.CILType.Equals(typeof(UFix))) && (!isArith || resultTypes[0].CILType.Equals(typeof(UFix))) && (isArith || resultTypes[0].CILType.Equals(typeof(bool)) || resultTypes[0].CILType.Equals(typeof(StdLogicVector)))) amode = ALU.EArithMode.Unsigned; else if (operandTypes.All(t => t.CILType.Equals(typeof(StdLogicVector))) && resultTypes[0].CILType.Equals(typeof(StdLogicVector))) amode = ALU.EArithMode.Unsigned; else if (operandTypes.All(t => t.CILType.Equals(typeof(StdLogic))) && resultTypes[0].CILType.Equals(typeof(StdLogicVector)) && (instr.Name == InstructionCodes.IsEq || instr.Name == InstructionCodes.IsNEq)) amode = ALU.EArithMode.Unsigned; else return null; osize0 = TypeLowering.Instance.GetWireWidth(operandTypes[0]); osize1 = TypeLowering.Instance.GetWireWidth(operandTypes[1]); rsize = TypeLowering.Instance.GetWireWidth(resultTypes[0]); ; switch (instr.Name) { case InstructionCodes.Add: op = ALU.EFunction.Add; break; case InstructionCodes.Sub: op = ALU.EFunction.Sub; break; case InstructionCodes.Mul: op = ALU.EFunction.Mul; break; case InstructionCodes.IsLt: case InstructionCodes.IsLte: case InstructionCodes.IsEq: case InstructionCodes.IsNEq: case InstructionCodes.IsGte: case InstructionCodes.IsGt: op = ALU.EFunction.Compare; break; default: throw new InvalidOperationException(); } } break; case InstructionCodes.Neg: { if (operandTypes[0].CILType.Equals(typeof(Signed)) && resultTypes[0].CILType.Equals(typeof(Signed))) amode = ALU.EArithMode.Signed; else if (operandTypes[0].CILType.Equals(typeof(SFix)) && resultTypes[0].CILType.Equals(typeof(SFix))) amode = ALU.EArithMode.Signed; else if (operandTypes[0].CILType.Equals(typeof(Unsigned)) && resultTypes[0].CILType.Equals(typeof(Unsigned))) amode = ALU.EArithMode.Unsigned; else if (operandTypes[0].CILType.Equals(typeof(UFix)) && resultTypes[0].CILType.Equals(typeof(UFix))) amode = ALU.EArithMode.Unsigned; else return null; osize0 = TypeLowering.Instance.GetWireWidth(operandTypes[0]); rsize = TypeLowering.Instance.GetWireWidth(resultTypes[0]); //alu = new ALU(ALU.EFunction.Neg, amode, 1, osize, 0, rsize); op = ALU.EFunction.Neg; } break; case InstructionCodes.And: case InstructionCodes.Or: { if (operandTypes.Length != 2 || resultTypes.Length != 1) return null; if (!((operandTypes[0].CILType.Equals(typeof(StdLogicVector)) && operandTypes[1].CILType.Equals(typeof(StdLogicVector)) && resultTypes[0].CILType.Equals(typeof(StdLogicVector))) || (operandTypes[0].CILType.Equals(typeof(Unsigned)) && operandTypes[1].CILType.Equals(typeof(Unsigned)) && resultTypes[0].CILType.Equals(typeof(Unsigned))))) return null; osize0 = TypeLowering.Instance.GetWireWidth(operandTypes[0]); osize1 = TypeLowering.Instance.GetWireWidth(operandTypes[1]); rsize = TypeLowering.Instance.GetWireWidth(resultTypes[0]); amode = ALU.EArithMode.Signed; switch (instr.Name) { case InstructionCodes.And: //alu = new ALU(ALU.EFunction.And, ALU.EArithMode.Signed, 0, osize0, osize1, rsize); op = ALU.EFunction.And; break; case InstructionCodes.Or: //alu = new ALU(ALU.EFunction.Or, ALU.EArithMode.Signed, 0, osize0, osize1, rsize); op = ALU.EFunction.Or; break; default: throw new NotImplementedException(); } } break; case InstructionCodes.Not: { if (operandTypes.Length != 1 || resultTypes.Length != 1) return null; if (!((operandTypes[0].CILType.Equals(typeof(StdLogicVector)) && resultTypes[0].CILType.Equals(typeof(StdLogicVector))))) return null; osize0 = TypeLowering.Instance.GetWireWidth(operandTypes[0]); rsize = TypeLowering.Instance.GetWireWidth(resultTypes[0]); //alu = new ALU(ALU.EFunction.Not, ALU.EArithMode.Unsigned, 0, osize, 0, rsize); amode = ALU.EArithMode.Unsigned; op = ALU.EFunction.Not; } break; default: return null; } int pdepth = CalcPipelineDepth(op, amode, osize0, osize1, rsize); ALU alu = new ALU(op, amode, pdepth, osize0, osize1, rsize); return TryMapOne(alu.Transactor, instr, operandTypes, resultTypes, false); }
public IXILMapping TryAllocate(Component host, XILInstr instr, TypeDescriptor[] operandTypes, TypeDescriptor[] resultTypes, IProject proj) { switch (instr.Name) { case InstructionCodes.Nop: case InstructionCodes.Barrier: if (instr.Operand is int) return new NopXILMapping(new NopTASite(host), (int)instr.Operand); else return new NopXILMapping(new NopTASite(host), 0); case InstructionCodes.Convert: if (TypeLowering.Instance.HasWireType(operandTypes[0]) && TypeLowering.Instance.HasWireType(resultTypes[0]) && !operandTypes[0].CILType.Equals(resultTypes[0].CILType)) { TypeDescriptor owt = TypeLowering.Instance.GetWireType(operandTypes[0]); TypeDescriptor rwt = TypeLowering.Instance.GetWireType(resultTypes[0]); if (!owt.Equals(rwt)) return null; return new IdXILMapping(new NopTASite(host)); } else { return null; } default: return null; } }
public IEnumerable<IXILMapping> TryMap(ITransactionSite taSite, XILInstr instr, TypeDescriptor[] operandTypes, TypeDescriptor[] resultTypes) { var fu = taSite.Host; var v = instr.Operand as FieldRef; if (v == null) yield break; var taLV = taSite as InlineFieldMapperTransactionSite; if (taLV == null) yield break; if (!taLV.Literal.Equals(v)) yield break; switch (instr.Name) { case InstructionCodes.LoadVar: yield return new ReadXILMapping(taLV); break; case InstructionCodes.StoreVar: yield return new WriteXILMapping(taLV); break; default: yield break; } }
public IXILMapping TryAllocate(Component host, XILInstr instr, TypeDescriptor[] operandTypes, TypeDescriptor[] resultTypes, IProject targetProject) { var v = instr.Operand as FieldRef; if (v == null) return null; var taSite = new InlineFieldMapperTransactionSite(this, host, v); switch (instr.Name) { case InstructionCodes.LoadVar: return new ReadXILMapping(taSite); case InstructionCodes.StoreVar: return new WriteXILMapping(taSite); default: return null; } }
public IEnumerable<IXILMapping> TryMap(ITransactionSite taSite, XILInstr instr, TypeDescriptor[] operandTypes, TypeDescriptor[] resultTypes) { var fu = taSite.Host; Slicer slicer = fu as Slicer; if (slicer == null) yield break; bool isSigned; int inputWidth, hiOffset, loOffset; if (!GetSliceParams(instr, operandTypes, resultTypes, out isSigned, out inputWidth, out hiOffset, out loOffset)) yield break; if (slicer.IsSigned != isSigned) yield break; if (slicer.InputWidth != inputWidth) yield break; if (hiOffset != slicer.HiOffset || loOffset != slicer.LoOffset) yield break; yield return new SlicerXILMapping(slicer); }
public IXILMapping TryAllocate(Component host, XILInstr instr, TypeDescriptor[] operandTypes, TypeDescriptor[] resultTypes, IProject proj) { if (instr.Name != InstructionCodes.Div && instr.Name != InstructionCodes.DivQF) return null; FixFormat fmtDividend = GetFixFormat(operandTypes[0]); FixFormat fmtDivisor = GetFixFormat(operandTypes[1]); FixFormat fmtQuotient = GetFixFormat(resultTypes[0]); if (fmtDividend == null || fmtDivisor == null || fmtQuotient == null) return null; FixFormat fmtFractional = null; if (instr.Name == InstructionCodes.DivQF) fmtFractional = GetFixFormat(resultTypes[1]); if (fmtDividend.IsSigned != fmtDivisor.IsSigned || fmtDividend.IsSigned != fmtQuotient.IsSigned) return null; if (fmtDividend.TotalWidth != fmtQuotient.TotalWidth) return null; int qFracWidth = fmtDividend.FracWidth - fmtDivisor.FracWidth; if (qFracWidth != fmtQuotient.FracWidth) return null; int fracWidth = 0; if (fmtFractional != null) fracWidth = fmtFractional.TotalWidth; XilinxDivider divider = new XilinxDivider() { DividendAndQuotientWidth = fmtDividend.TotalWidth, DivisorWidth = fmtDivisor.TotalWidth, FractionWidth = fracWidth, OperandSign = fmtDividend.IsSigned ? XilinxDivider.ESignedness.Signed : XilinxDivider.ESignedness.Unsigned, AlgorithmType = XilinxDivider.ERadix.HighRadix, RemainderType = XilinxDivider.ERemainder.Fractional, HasCE = false, HasSCLR = false, DivideByZeroDetect = false, LatencyConfiguration = XilinxDivider.ELatencyConfiguration.Manual, ClocksPerDivision = 1 }; int min = divider.MinLatency; int max = divider.MaxLatency; int scaledStages = (int)Math.Round(min + Config.PipeStageScaling * (max - min)); if (scaledStages < min) scaledStages = min; else if (scaledStages > max) scaledStages = max; divider.Latency = scaledStages; return new DividerXILMapping(divider); }
public IXILMapping TryAllocate(Component host, XILInstr instr, TypeDescriptor[] operandTypes, TypeDescriptor[] resultTypes, IProject proj) { bool isSigned; int inputWidth, hiOffset, loOffset; if (!GetSliceParams(instr, operandTypes, resultTypes, out isSigned, out inputWidth, out hiOffset, out loOffset)) return null; if (inputWidth == 0 || (hiOffset - loOffset + 1) <= 0) return null; var slicer = new Slicer(inputWidth, hiOffset, loOffset, isSigned); return new SlicerXILMapping(slicer); }
public IEnumerable<IXILMapping> TryMap(ITransactionSite taSite, XILInstr instr, TypeDescriptor[] operandTypes, TypeDescriptor[] resultTypes) { IXILMapping alt0 = null, alt1 = null; alt0 = TryMapOne(taSite, instr, operandTypes, resultTypes, false); switch (instr.Name) { case InstructionCodes.Add: case InstructionCodes.Mul: case InstructionCodes.And: case InstructionCodes.Or: case InstructionCodes.IsEq: case InstructionCodes.IsNEq: // These operations are commutative => "a op b", "b op a" are both feasible alt1 = TryMapOne(taSite, instr, new TypeDescriptor[] { operandTypes[1], operandTypes[0] }, resultTypes, true); break; case InstructionCodes.IsGt: alt1 = TryMapOne(taSite, DefaultInstructionSet.Instance.IsLt(), new TypeDescriptor[] { operandTypes[1], operandTypes[0] }, resultTypes, true); break; case InstructionCodes.IsGte: alt1 = TryMapOne(taSite, DefaultInstructionSet.Instance.IsLte(), new TypeDescriptor[] { operandTypes[1], operandTypes[0] }, resultTypes, true); break; case InstructionCodes.IsLt: alt1 = TryMapOne(taSite, DefaultInstructionSet.Instance.IsGt(), new TypeDescriptor[] { operandTypes[1], operandTypes[0] }, resultTypes, true); break; case InstructionCodes.IsLte: alt1 = TryMapOne(taSite, DefaultInstructionSet.Instance.IsGte(), new TypeDescriptor[] { operandTypes[1], operandTypes[0] }, resultTypes, true); break; } if (alt0 != null) yield return alt0; if (alt1 != null) yield return alt1; }
private bool CheckFixComplianceInternal(XILInstr instr, TypeDescriptor[] operandTypes, TypeDescriptor[] resultTypes) { if (!operandTypes[0].CILType.Equals(typeof(SFix)) && !operandTypes[0].CILType.Equals(typeof(UFix))) { return true; } dynamic smp0 = operandTypes[0].GetSampleInstance(); dynamic smp1 = operandTypes.Length > 1 ? operandTypes[1].GetSampleInstance() : null; dynamic smpr = resultTypes[0].GetSampleInstance(); object smpe; try { switch (instr.Name) { case InstructionCodes.Add: case InstructionCodes.Sub: smpe = smp0 + smp1; break; case InstructionCodes.Mul: smpe = smp0 * smp1; break; case InstructionCodes.Neg: smpe = -smp0; break; default: return true; } } catch (Exception) { return false; } var fmtr = resultTypes[0].GetFixFormat(); var fmte = TypeDescriptor.GetTypeOf(smpe).GetFixFormat(); return fmte.FracWidth == fmtr.FracWidth; }
public IEnumerable<IXILMapping> TryMap(ITransactionSite taSite, XILInstr instr, TypeDescriptor[] operandTypes, TypeDescriptor[] resultTypes) { var fu = taSite.Host; MUX2 mux2 = fu as MUX2; if (mux2 == null) yield break; if (instr.Name != InstructionCodes.Select) yield break; int width = TypeLowering.Instance.GetWireWidth(operandTypes[1]); if (width != mux2.Width) yield break; yield return new MUX2XILMapping(mux2.TASite); }
public IXILMapping TryAllocate(Component host, XILInstr instr, TypeDescriptor[] operandTypes, TypeDescriptor[] resultTypes, IProject proj) { XilinxProject xproj = proj as XilinxProject; if (xproj == null) return null; Type otype = operandTypes[0].CILType; if (!operandTypes.All(t => t.CILType.Equals(otype))) return null; Type rtype = resultTypes[0].CILType; FloatingPointCore fpu = null; CoreConfiguration cfg = null; switch (instr.Name) { case InstructionCodes.Add: case InstructionCodes.Sub: { FloatingPointCore.EPrecision prec = FloatingPointCore.EPrecision.Single; if (otype.Equals(typeof(float))) prec = FloatingPointCore.EPrecision.Single; else if (otype.Equals(typeof(double))) prec = FloatingPointCore.EPrecision.Double; else return null; fpu = new FloatingPointCore() { Function = FloatingPointCore.EFunction.AddSubtract, Precision = prec, ResultPrecision = prec, }; cfg = Config[prec, FloatingPointCore.EFunction.AddSubtract]; if (cfg.UseDedicatedAddSub) { if (instr.Name.Equals(InstructionCodes.Add)) fpu.AddSubSel = FloatingPointCore.EAddSub.Add; else fpu.AddSubSel = FloatingPointCore.EAddSub.Subtract; } else { fpu.AddSubSel = FloatingPointCore.EAddSub.Both; } } break; case InstructionCodes.IsEq: case InstructionCodes.IsGt: case InstructionCodes.IsGte: case InstructionCodes.IsLt: case InstructionCodes.IsLte: case InstructionCodes.IsNEq: { FloatingPointCore.EPrecision prec = FloatingPointCore.EPrecision.Single; if (otype.Equals(typeof(float))) prec = FloatingPointCore.EPrecision.Single; else if (otype.Equals(typeof(double))) prec = FloatingPointCore.EPrecision.Double; else return null; fpu = new FloatingPointCore() { Function = FloatingPointCore.EFunction.Compare, Precision = prec }; cfg = Config[prec, FloatingPointCore.EFunction.Compare]; if (cfg.UseDedicatedCmp) { switch (instr.Name) { case InstructionCodes.IsEq: fpu.CompareSel = FloatingPointCore.ECompareOp.Equal; break; case InstructionCodes.IsGt: fpu.CompareSel = FloatingPointCore.ECompareOp.GreaterThan; break; case InstructionCodes.IsGte: fpu.CompareSel = FloatingPointCore.ECompareOp.GreaterThanOrEqual; break; case InstructionCodes.IsLt: fpu.CompareSel = FloatingPointCore.ECompareOp.LessThan; break; case InstructionCodes.IsLte: fpu.CompareSel = FloatingPointCore.ECompareOp.LessThanOrEqual; break; case InstructionCodes.IsNEq: fpu.CompareSel = FloatingPointCore.ECompareOp.NotEqual; break; default: throw new NotImplementedException(); } } else { fpu.CompareSel = FloatingPointCore.ECompareOp.Programmable; } fpu.ResultPrecision = FloatingPointCore.EPrecision.Custom; fpu.ResultExponentWidth = 1; fpu.ResultFractionWidth = 0; } break; case InstructionCodes.Mul: { FloatingPointCore.EPrecision prec = FloatingPointCore.EPrecision.Single; if (otype.Equals(typeof(float))) prec = FloatingPointCore.EPrecision.Single; else if (otype.Equals(typeof(double))) prec = FloatingPointCore.EPrecision.Double; else return null; fpu = new FloatingPointCore() { Function = FloatingPointCore.EFunction.Multiply, Precision = prec, ResultPrecision = prec }; cfg = Config[prec, FloatingPointCore.EFunction.Multiply]; } break; case InstructionCodes.Div: { FloatingPointCore.EPrecision prec = FloatingPointCore.EPrecision.Single; if (otype.Equals(typeof(float))) prec = FloatingPointCore.EPrecision.Single; else if (otype.Equals(typeof(double))) prec = FloatingPointCore.EPrecision.Double; else return null; fpu = new FloatingPointCore() { Function = FloatingPointCore.EFunction.Divide, Precision = prec, ResultPrecision = prec }; cfg = Config[prec, FloatingPointCore.EFunction.Divide]; } break; case InstructionCodes.Sqrt: { FloatingPointCore.EPrecision prec = FloatingPointCore.EPrecision.Single; if (otype.Equals(typeof(float))) prec = FloatingPointCore.EPrecision.Single; else if (otype.Equals(typeof(double))) prec = FloatingPointCore.EPrecision.Double; else return null; fpu = new FloatingPointCore() { Function = FloatingPointCore.EFunction.SquareRoot, Precision = prec, ResultPrecision = prec }; cfg = Config[prec, FloatingPointCore.EFunction.SquareRoot]; } break; case InstructionCodes.Convert: { FloatingPointCore.EPrecision inprec = FloatingPointCore.EPrecision.Single; bool infloat = false; FixFormat infmt = null; if (otype.Equals(typeof(float))) { inprec = FloatingPointCore.EPrecision.Single; infloat = true; } else if (otype.Equals(typeof(double))) { inprec = FloatingPointCore.EPrecision.Double; infloat = true; } else if (otype.Equals(typeof(SFix)) || otype.Equals(typeof(Signed))) { inprec = FloatingPointCore.EPrecision.Custom; infloat = false; infmt = SFix.GetFormat(operandTypes[0]); } else { return null; } FloatingPointCore.EPrecision outprec = FloatingPointCore.EPrecision.Single; bool outfloat = false; FixFormat outfmt = null; if (rtype.Equals(typeof(float))) { outprec = FloatingPointCore.EPrecision.Single; outfloat = true; } else if (rtype.Equals(typeof(double))) { outprec = FloatingPointCore.EPrecision.Double; outfloat = true; } else if (rtype.Equals(typeof(SFix)) || rtype.Equals(typeof(Signed))) { outprec = FloatingPointCore.EPrecision.Custom; outfloat = false; outfmt = SFix.GetFormat(resultTypes[0]); } else { return null; } FloatingPointCore.EFunction func; if (!infloat && !outfloat) return null; else if (infloat && outfloat) func = FloatingPointCore.EFunction.FloatToFloat; else if (infloat) func = FloatingPointCore.EFunction.FloatToFixed; else func = FloatingPointCore.EFunction.FixedToFloat; fpu = new FloatingPointCore() { Function = func, Precision = inprec, ResultPrecision = outprec }; if (infmt != null) { fpu.ExponentWidth = infmt.IntWidth; fpu.FractionWidth = infmt.FracWidth; } if (outfmt != null) { fpu.ResultExponentWidth = outfmt.IntWidth; fpu.ResultFractionWidth = outfmt.FracWidth; } FloatingPointCore.EPrecision prec = infloat ? inprec : outprec; cfg = Config[prec, FloatingPointCore.EFunction.Multiply]; } break; default: return null; } fpu.TargetDeviceFamily = xproj.DeviceFamily; fpu.TargetISEVersion = xproj.ISEVersion; if (cfg.EnableDeviceCapabilityDependentDSPUsage) { switch (fpu.Function) { case FloatingPointCore.EFunction.Multiply: switch (xproj.DeviceFamily) { case EDeviceFamily.Spartan3: case EDeviceFamily.Spartan3A_3AN: case EDeviceFamily.Spartan3E: case EDeviceFamily.Automotive_Spartan3: case EDeviceFamily.Automotive_Spartan3A: case EDeviceFamily.Automotive_Spartan3E: if (cfg.DSPUsageRatio < 0.5f) fpu.DSP48EUsage = FloatingPointCore.EDSP48EUsage.FullUsage; else fpu.DSP48EUsage = FloatingPointCore.EDSP48EUsage.NoUsage; break; default: if (cfg.DSPUsageRatio < 0.25f) fpu.DSP48EUsage = FloatingPointCore.EDSP48EUsage.NoUsage; else if (cfg.DSPUsageRatio < 0.50f) fpu.DSP48EUsage = FloatingPointCore.EDSP48EUsage.MediumUsage; else if (cfg.DSPUsageRatio < 0.75f) fpu.DSP48EUsage = FloatingPointCore.EDSP48EUsage.MaxUsage; else fpu.DSP48EUsage = FloatingPointCore.EDSP48EUsage.FullUsage; break; } break; case FloatingPointCore.EFunction.AddSubtract: if (fpu.Precision == FloatingPointCore.EPrecision.Custom) { fpu.DSP48EUsage = FloatingPointCore.EDSP48EUsage.NoUsage; } else { switch (xproj.DeviceFamily) { case EDeviceFamily.Virtex4: case EDeviceFamily.Virtex5: case EDeviceFamily.Virtex6: case EDeviceFamily.Virtex6_LowPower: if (cfg.DSPUsageRatio < 0.5f) fpu.DSP48EUsage = FloatingPointCore.EDSP48EUsage.NoUsage; else fpu.DSP48EUsage = FloatingPointCore.EDSP48EUsage.FullUsage; break; default: fpu.DSP48EUsage = FloatingPointCore.EDSP48EUsage.NoUsage; break; } } break; default: fpu.DSP48EUsage = FloatingPointCore.EDSP48EUsage.NoUsage; break; } } else { fpu.DSP48EUsage = cfg.DSP48EUsage; } fpu.HasCE = cfg.HasCE; fpu.HasDivideByZero = cfg.HasDivideByZero; fpu.HasInvalidOp = cfg.HasInvalidOp; fpu.HasOperationND = cfg.HasOperationND; fpu.HasOperationRFD = cfg.HasOperationRFD; fpu.HasOverflow = cfg.HasOverflow; fpu.HasRdy = cfg.HasRdy; fpu.HasSCLR = cfg.HasSCLR; if (cfg.UseMaximumLatency) { fpu.UseMaximumLatency = true; } else if (cfg.SpecifyLatencyRatio) { fpu.UseMaximumLatency = false; fpu.Latency = (int)(cfg.LatencyRatio * fpu.MaximumLatency); } else { fpu.Latency = cfg.Latency; } IXILMapping result = TryMapOne(fpu.TASite, instr, operandTypes, resultTypes, false); Debug.Assert(result != null); return result; }
public IXILMapping TryAllocate(Component host, XILInstr instr, TypeDescriptor[] operandTypes, TypeDescriptor[] resultTypes, IProject proj) { if (instr.Name != InstructionCodes.Select) return null; int width = TypeLowering.Instance.GetWireWidth(operandTypes[1]); MUX2 mux2 = new MUX2(width); return new MUX2XILMapping(mux2.TASite); }
public IXILMapping TryMapOne(ITransactionSite taSite, XILInstr instr, TypeDescriptor[] operandTypes, TypeDescriptor[] resultTypes, bool swap) { var fu = taSite.Host; FloatingPointCore fpu = (FloatingPointCore)fu; if (fpu == null) return null; if (operandTypes.Length != fpu.Arity) return null; if (fpu.Function == FloatingPointCore.EFunction.AddSubtract || fpu.Function == FloatingPointCore.EFunction.Compare || fpu.Function == FloatingPointCore.EFunction.Divide || fpu.Function == FloatingPointCore.EFunction.FloatToFixed || fpu.Function == FloatingPointCore.EFunction.FloatToFloat || fpu.Function == FloatingPointCore.EFunction.Multiply || fpu.Function == FloatingPointCore.EFunction.SquareRoot) { Type itype = null; switch (fpu.Precision) { case FloatingPointCore.EPrecision.Single: itype = typeof(float); break; case FloatingPointCore.EPrecision.Double: itype = typeof(double); break; default: return null; } foreach (TypeDescriptor otype in operandTypes) if (!otype.CILType.Equals(itype)) return null; } Func<ISignalSource<StdLogicVector>[], ISignalSink<StdLogicVector>[], IEnumerable<TAVerb>> realize = null; ISignalSource<StdLogicVector> defOp = SignalSource.Create(StdLogicVector._0s(fpu.OperandWidth)); ISignalSink<StdLogicVector> defR = SignalSink.Nil<StdLogicVector>(); switch (fpu.Function) { case FloatingPointCore.EFunction.AddSubtract: if (instr.Name.Equals(InstructionCodes.Add) && (fpu.AddSubSel == FloatingPointCore.EAddSub.Add || fpu.AddSubSel == FloatingPointCore.EAddSub.Both)) { realize = (os, rs) => fpu.TASite.Add(os[0], os[1], rs[0]); } else if (instr.Name.Equals(InstructionCodes.Sub) && (fpu.AddSubSel == FloatingPointCore.EAddSub.Subtract || fpu.AddSubSel == FloatingPointCore.EAddSub.Both)) { realize = (os, rs) => fpu.TASite.Sub(os[0], os[1], rs[0]); } else return null; break; case FloatingPointCore.EFunction.Compare: if (instr.Name.Equals(InstructionCodes.IsLt)) { realize = (os, rs) => fpu.TASite.IsLt(os[0], os[1], rs[0]); } else if (instr.Name.Equals(InstructionCodes.IsLte)) { realize = (os, rs) => fpu.TASite.IsLte(os[0], os[1], rs[0]); } else if (instr.Name.Equals(InstructionCodes.IsEq)) { realize = (os, rs) => fpu.TASite.IsEq(os[0], os[1], rs[0]); } else if (instr.Name.Equals(InstructionCodes.IsNEq)) { realize = (os, rs) => fpu.TASite.IsNEq(os[0], os[1], rs[0]); } else if (instr.Name.Equals(InstructionCodes.IsGte)) { realize = (os, rs) => fpu.TASite.IsGte(os[0], os[1], rs[0]); } else if (instr.Name.Equals(InstructionCodes.IsGt)) { realize = (os, rs) => fpu.TASite.IsGt(os[0], os[1], rs[0]); } else { return null; } break; case FloatingPointCore.EFunction.Divide: if (instr.Name.Equals(InstructionCodes.Div)) { realize = (os, rs) => fpu.TASite.Div(os[0], os[1], rs[0]); } else return null; break; case FloatingPointCore.EFunction.FixedToFloat: if (instr.Name.Equals(InstructionCodes.Convert)) { if (!operandTypes[0].CILType.Equals(typeof(SFix)) && !operandTypes[0].CILType.Equals(typeof(Signed))) return null; FixFormat ffmt = SFix.GetFormat(operandTypes[0]); if (ffmt.IntWidth != fpu.ExponentWidth || ffmt.FracWidth != fpu.FractionWidth) return null; switch (fpu.ResultPrecision) { case FloatingPointCore.EPrecision.Single: if (!resultTypes[0].CILType.Equals(typeof(float))) return null; break; case FloatingPointCore.EPrecision.Double: if (!resultTypes[0].CILType.Equals(typeof(double))) return null; break; default: return null; } realize = (os, rs) => fpu.TASite.Fix2Float(os[0], rs[0]); } else return null; break; case FloatingPointCore.EFunction.FloatToFixed: if (instr.Name.Equals(InstructionCodes.Convert)) { if (!resultTypes[0].CILType.Equals(typeof(SFix)) && !resultTypes[0].CILType.Equals(typeof(Signed))) return null; FixFormat ffmt = SFix.GetFormat(resultTypes[0]); if (ffmt.IntWidth != fpu.ResultExponentWidth || ffmt.FracWidth != fpu.ResultFractionWidth) return null; switch (fpu.Precision) { case FloatingPointCore.EPrecision.Single: if (!operandTypes[0].CILType.Equals(typeof(float))) return null; break; case FloatingPointCore.EPrecision.Double: if (!operandTypes[0].CILType.Equals(typeof(double))) return null; break; default: return null; } realize = (os, rs) => fpu.TASite.Float2Fix(os[0], rs[0]); } else return null; break; case FloatingPointCore.EFunction.FloatToFloat: if (instr.Name.Equals(InstructionCodes.Convert)) { switch (fpu.Precision) { case FloatingPointCore.EPrecision.Single: if (!operandTypes[0].CILType.Equals(typeof(float))) return null; break; case FloatingPointCore.EPrecision.Double: if (!operandTypes[0].CILType.Equals(typeof(double))) return null; break; default: return null; } switch (fpu.ResultPrecision) { case FloatingPointCore.EPrecision.Single: if (!resultTypes[0].CILType.Equals(typeof(float))) return null; break; case FloatingPointCore.EPrecision.Double: if (!resultTypes[0].CILType.Equals(typeof(double))) return null; break; default: return null; } realize = (os, rs) => fpu.TASite.Float2Float(os[0], rs[0]); } else return null; break; case FloatingPointCore.EFunction.Multiply: if (instr.Name.Equals(InstructionCodes.Mul)) { realize = (os, rs) => fpu.TASite.Mul(os[0], os[1], rs[0]); } else return null; break; case FloatingPointCore.EFunction.SquareRoot: if (instr.Name.Equals(InstructionCodes.Sqrt)) { realize = (os, rs) => fpu.TASite.Sqrt(os[0], rs[0]); } else return null; break; default: throw new NotImplementedException(); } return new XILMapping(fpu.TASite, realize, swap); }
public IEnumerable<IXILMapping> TryMap(ITransactionSite taSite, XILInstr instr, TypeDescriptor[] operandTypes, TypeDescriptor[] resultTypes) { var fu = taSite.Host; Concatenizer cc = fu as Concatenizer; if (cc == null) yield break; if (instr.Name != InstructionCodes.Concat) yield break; if (!operandTypes[0].CILType.Equals(typeof(StdLogicVector)) || !resultTypes[0].CILType.Equals(typeof(StdLogicVector))) yield break; if (!operandTypes.All(t => t.Equals(operandTypes[0]))) yield break; int wordWidth = (int)operandTypes[0].TypeParams[0]; if (cc.WordWidth != wordWidth || cc.NumWords != operandTypes.Length) yield break; yield return new ConcatXILMapping(cc); }
private IXILMapping TryMapOne(ITransactionSite taSite, XILInstr instr, TypeDescriptor[] operandTypes, TypeDescriptor[] resultTypes, bool swap) { var fu = taSite.Host; ALU alu = fu as ALU; if (alu == null) return null; if (resultTypes.Length != 1) return null; TypeDescriptor rtype = resultTypes[0]; if (!rtype.IsComplete) return null; if (!CheckFixCompliance(instr, operandTypes, resultTypes)) return null; int rsize = TypeLowering.Instance.GetWireWidth(rtype); int[] osizes = operandTypes.Select(t => TypeLowering.Instance.GetWireWidth(t)).ToArray(); Func<ISignalSource<StdLogicVector>[], ISignalSink<StdLogicVector>[], IEnumerable<TAVerb>> realize; if (operandTypes.Length == 1) { realize = (os, rs) => alu.Transactor.Do(os[0], rs[0]); TypeDescriptor otype = operandTypes[0]; long osize = osizes[0]; switch (instr.Name) { case InstructionCodes.Neg: if (alu.FuncSel != ALU.EFunction.Neg) return null; if ((!otype.CILType.Equals(typeof(Signed)) || !rtype.CILType.Equals(typeof(Signed))) && (!otype.CILType.Equals(typeof(SFix)) || !rtype.CILType.Equals(typeof(SFix)))) return null; if (alu.AWidth != osize || alu.RWidth != rsize) return null; break; case InstructionCodes.Not: if (alu.FuncSel != ALU.EFunction.Not) return null; if (!otype.CILType.Equals(typeof(StdLogicVector)) || !rtype.CILType.Equals(typeof(StdLogicVector))) return null; if (alu.AWidth != osize || alu.RWidth != osize) return null; break; default: return null; } } else { realize = (os, rs) => alu.Transactor.Do(os[0], os[1], rs[0]); TypeDescriptor otype0 = operandTypes[0]; TypeDescriptor otype1 = operandTypes[1]; long osize0 = osizes[0]; long osize1 = osizes[1]; if (alu.AWidth != osize0 || alu.BWidth != osize1 || (alu.FuncSel != ALU.EFunction.Compare && alu.RWidth != rsize)) return null; bool isArith = false; switch (instr.Name) { case InstructionCodes.Add: case InstructionCodes.Sub: case InstructionCodes.Mul: isArith = true; goto case InstructionCodes.IsLt; case InstructionCodes.IsLt: case InstructionCodes.IsLte: case InstructionCodes.IsEq: case InstructionCodes.IsNEq: case InstructionCodes.IsGte: case InstructionCodes.IsGt: switch (alu.ArithMode) { case ALU.EArithMode.Signed: if ((!otype0.CILType.Equals(typeof(Signed)) || !otype1.CILType.Equals(typeof(Signed)) || (isArith && !rtype.CILType.Equals(typeof(Signed))) || (!isArith && !rtype.CILType.Equals(typeof(bool)) && !rtype.CILType.Equals(typeof(StdLogicVector)))) && (!otype0.CILType.Equals(typeof(SFix)) || !otype1.CILType.Equals(typeof(SFix)) || (isArith && !rtype.CILType.Equals(typeof(SFix))) || (!isArith && !rtype.CILType.Equals(typeof(bool)) && !rtype.CILType.Equals(typeof(StdLogicVector))))) return null; break; case ALU.EArithMode.Unsigned: if ((!(otype0.CILType.Equals(typeof(Unsigned)) || otype0.CILType.Equals(typeof(StdLogicVector))) || !(otype1.CILType.Equals(typeof(Unsigned)) || otype1.CILType.Equals(typeof(StdLogicVector))) || (isArith && !(rtype.CILType.Equals(typeof(Unsigned)) || rtype.CILType.Equals(typeof(StdLogicVector)))) || (!isArith && !rtype.CILType.Equals(typeof(bool)) && !rtype.CILType.Equals(typeof(StdLogicVector)))) && (!(otype0.CILType.Equals(typeof(UFix)) || otype0.CILType.Equals(typeof(StdLogicVector)) || otype0.CILType.Equals(typeof(StdLogic))) || !(otype1.CILType.Equals(typeof(UFix)) || otype1.CILType.Equals(typeof(StdLogicVector)) || otype1.CILType.Equals(typeof(StdLogic))) || (isArith && !rtype.CILType.Equals(typeof(UFix))) || (!isArith && !rtype.CILType.Equals(typeof(bool)) && !rtype.CILType.Equals(typeof(StdLogicVector))))) return null; break; default: throw new NotImplementedException(); } switch (alu.FuncSel) { case ALU.EFunction.Add: if (!instr.Name.Equals(InstructionCodes.Add)) return null; break; case ALU.EFunction.Sub: if (!instr.Name.Equals(InstructionCodes.Sub)) return null; break; case ALU.EFunction.Mul: if (!instr.Name.Equals(InstructionCodes.Mul)) return null; break; case ALU.EFunction.Compare: switch (instr.Name) { case InstructionCodes.IsLt: realize = (os, rs) => alu.Transactor.IsLt(os[0], os[1], rs[0]); break; case InstructionCodes.IsLte: realize = (os, rs) => alu.Transactor.IsLte(os[0], os[1], rs[0]); break; case InstructionCodes.IsEq: realize = (os, rs) => alu.Transactor.IsEq(os[0], os[1], rs[0]); break; case InstructionCodes.IsNEq: realize = (os, rs) => alu.Transactor.IsNEq(os[0], os[1], rs[0]); break; case InstructionCodes.IsGte: realize = (os, rs) => alu.Transactor.IsGte(os[0], os[1], rs[0]); break; case InstructionCodes.IsGt: realize = (os, rs) => alu.Transactor.IsGt(os[0], os[1], rs[0]); break; default: return null; } break; } break; case InstructionCodes.And: if (alu.FuncSel != ALU.EFunction.And) return null; break; case InstructionCodes.Or: if (alu.FuncSel != ALU.EFunction.Or) return null; break; } } return new ALUXILMapping(alu.Transactor, realize, swap); }
public IXILMapping TryMapOne(ITransactionSite taSite, XILInstr instr, TypeDescriptor[] operandTypes, TypeDescriptor[] resultTypes, bool swap) { var fu = taSite.Host; var asub = fu as XilinxAdderSubtracter; if (asub == null) return null; bool iisAdd = instr.Name == InstructionCodes.Add; bool iisSub = instr.Name == InstructionCodes.Sub; if ((asub.AddMode == XilinxAdderSubtracter.EAddMode.Add && !iisAdd) || (asub.AddMode == XilinxAdderSubtracter.EAddMode.Subtract && !iisSub) || (!iisAdd && !iisSub)) return null; FixFormat fmta, fmtb, fmtr; fmta = GetFixFormat(operandTypes[0]); fmtb = GetFixFormat(operandTypes[1]); fmtr = GetFixFormat(resultTypes[0]); if (fmta == null || fmtb == null || fmtr == null) return null; bool expectSigned = fmta.IsSigned || fmtb.IsSigned; if (expectSigned != fmtr.IsSigned) return null; if (fmta.FracWidth != fmtb.FracWidth || fmtr.FracWidth != fmta.FracWidth) return null; if (fmta.TotalWidth != asub.Awidth || fmtb.TotalWidth != asub.Bwidth || fmtr.TotalWidth != asub.OutWidth) return null; return new XILMapping(asub, iisAdd, swap); }
public IEnumerable<IXILMapping> TryMap(ITransactionSite taSite, XILInstr instr, TypeDescriptor[] operandTypes, TypeDescriptor[] resultTypes) { IFixedAbsTransactionSite fats = taSite as IFixedAbsTransactionSite; if (fats == null) yield break; if (instr.Name != InstructionCodes.Abs) yield break; var operandFormat = operandTypes[0].GetFixFormat(); if (operandFormat == null) yield break; var resultFormat = resultTypes[0].GetFixFormat(); if (resultFormat == null) yield break; if (operandFormat.FracWidth != resultFormat.FracWidth) yield break; if (operandFormat.TotalWidth != fats.Host.InputWidth) yield break; if (resultFormat.TotalWidth != fats.Host.OutputWidth) yield break; yield return new AbsMapping(fats.Host); }
public IXILMapping TryAllocate(Component host, XILInstr instr, TypeDescriptor[] operandTypes, TypeDescriptor[] resultTypes, IProject targetProject) { if (instr.Name != InstructionCodes.Abs) return null; var operandFormat = operandTypes[0].GetFixFormat(); if (operandFormat == null) return null; var resultFormat = resultTypes[0].GetFixFormat(); if (resultFormat == null) return null; if (operandFormat.FracWidth != resultFormat.FracWidth) return null; var fu = new FixedAbs( operandFormat.TotalWidth, resultFormat.TotalWidth, ComputeLatency(operandFormat.TotalWidth, resultFormat.TotalWidth)); return new AbsMapping(fu); }
public IEnumerable<IXILMapping> TryMap(ITransactionSite taSite, XILInstr instr, TypeDescriptor[] operandTypes, TypeDescriptor[] resultTypes) { IXILMapping alt0, alt1 = null; alt0 = TryMapOne(taSite, instr, operandTypes, resultTypes, false); switch (instr.Name) { case InstructionCodes.Add: alt1 = TryMapOne(taSite, instr, new TypeDescriptor[] { operandTypes[1], operandTypes[0] }, resultTypes, true); break; } if (alt0 != null) yield return alt0; if (alt1 != null) yield return alt1; }