Example #1
0
        private void ImplementIf(IList <Expression> conds, IList <Statement> branches)
        {
            BranchLabel[] skipTargets = new BranchLabel[conds.Count];
            BranchLabel   beyond      = CreateLabel();

            for (int i = 0; i < conds.Count; i++)
            {
                Expression cond = conds[i].SimplifyMultiValuedLogic();
                cond.Accept(this);
                BranchLabel target = CreateLabel();
                skipTargets[i] = target;
                XILInstr bi = ISet.BranchIfFalse(target);
                Emit(bi, CloseBB(), 1);
                BeginBB();
                branches[i].Accept(this);
                target.InstructionIndex = NextInstructionIndex;
                if (i != branches.Count - 1)
                {
                    Emit(ISet.Goto(beyond), CloseBB(), 0);
                }
                BeginBB();
            }
            skipTargets.Last().InstructionIndex = NextInstructionIndex;
            if (conds.Count < branches.Count)
            {
                branches.Last().Accept(this);
                BeginBB();
            }
            beyond.InstructionIndex = NextInstructionIndex;
        }
Example #2
0
 /// <summary>
 /// Constructs an instance
 /// </summary>
 /// <param name="command">underlying XIL instruction</param>
 /// <param name="preds">instruction dependencies</param>
 /// <param name="operandSlots">operand slots</param>
 /// <param name="resultSlots">result slots</param>
 public XIL3Instr(XILInstr command,
                  InstructionDependency[] preds, int[] operandSlots, int[] resultSlots)
 {
     Command      = command;
     Preds        = preds;
     OperandSlots = operandSlots;
     ResultSlots  = resultSlots;
     Index        = -1;
     CILRef       = null;
 }
Example #3
0
        public override bool Equals(object obj)
        {
            XILInstr xili = obj as XILInstr;

            if (xili == null)
            {
                return(false);
            }

            return(Name.Equals(xili.Name) &&
                   object.Equals(Operand, xili.Operand));
        }
Example #4
0
        /// <summary>
        /// Constructs a new instance
        /// </summary>
        /// <param name="command">XIL instruction</param>
        /// <param name="preds">instruction dependencies</param>
        /// <param name="operandTypes">operand types expected on the stack</param>
        /// <param name="resultTypes">result types to appear on the stack</param>
        public XILSInstr(XILInstr command, InstructionDependency[] preds,
                         TypeDescriptor[] operandTypes, TypeDescriptor[] resultTypes)
        {
            Contract.Requires(command != null && preds != null &&
                              operandTypes != null && operandTypes.All(t => t != null) &&
                              resultTypes != null && resultTypes.All(t => t != null));

            Command      = command;
            Preds        = preds;
            OperandTypes = operandTypes;
            ResultTypes  = resultTypes;

            CILRef = null;
        }
Example #5
0
        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);
        }
Example #6
0
        private void Emit(XILInstr xili, object backRef, InstructionDependency[] preds, int numOperands, params TypeDescriptor[] resultTypes)
        {
            Contract.Requires(xili != null && preds != null && numOperands >= 0 &&
                              resultTypes != null && resultTypes.All(t => t != null));

            xili.BackRef = backRef;
            TypeDescriptor[] operandTypes = new TypeDescriptor[numOperands];
            for (int i = numOperands - 1; i >= 0; i--)
            {
                operandTypes[i] = _typeStack.Pop();
            }
            for (int i = 0; i < resultTypes.Length; i++)
            {
                _typeStack.Push(resultTypes[i]);
            }
            Emit(xili.CreateStk(preds, operandTypes, resultTypes));
        }
Example #7
0
        /// <summary>
        /// Classifies a given XIL instruction, such that all instructions which may be mapped to the same type of hardware functional unit
        /// belong to the same group.
        /// </summary>
        /// <param name="instr">XIL instruction</param>
        /// <param name="operandTypes">types of instruction operands</param>
        /// <param name="resultTypes">types of instruction results</param>
        /// <param name="binder">binder service</param>
        /// <returns>Opaque group identifier. Do not make any assumptions on the content or type of the returned object.
        /// The important thing is that any instructions belonging to the same group will see the same object.</returns>
        public object Classify(XILInstr instr, TypeDescriptor[] operandTypes, TypeDescriptor[] resultTypes, IAutoBinder binder)
        {
            var mapping = TryMap(instr, operandTypes, resultTypes, binder);

            if (mapping == null)
            {
                return(null);
            }
            if (mapping.ResourceKind == EMappingKind.ExclusiveResource ||
                mapping.ResourceKind == EMappingKind.LightweightResource)
            {
                return(new ClassifyCookie(instr));
            }
            else
            {
                return(mapping.TASite);
            }
        }
Example #8
0
 private void Emit(XILInstr xili, object backRef, int numOperands, params TypeDescriptor[] resultTypes)
 {
     if (_closeBBOnNextInstr)
     {
         Emit(xili, backRef, CloseBB(), numOperands, resultTypes);
         _closeBBOnNextInstr = false;
     }
     else
     {
         int pred = _barriers[xili.Name];
         if (pred >= 0)
         {
             Emit(xili, backRef, new InstructionDependency[] { new OrderDependency(pred, OrderDependency.EKind.BeginAfter) }, numOperands, resultTypes);
         }
         else
         {
             Emit(xili, backRef, new InstructionDependency[0], numOperands, resultTypes);
         }
     }
 }
Example #9
0
        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));
            }
        }
Example #10
0
        /// <summary>
        /// Tries to map the given XIL instruction to any suitable functional unit. This call will not create any actual hardware. It is used by the
        /// scheduler to query basic instruction metrics, namely initiation interval and latency.
        /// </summary>
        /// <param name="instr">XIL instruction</param>
        /// <param name="operandTypes">operand types of XIL instruction</param>
        /// <param name="resultTypes">result types of XIL instruction</param>
        /// <param name="binder">binder service</param>
        /// <returns>a hardware mapping for the supplied instruction or null if no such exists</returns>
        public IXILMapping TryMap(XILInstr instr, TypeDescriptor[] operandTypes, TypeDescriptor[] resultTypes, IAutoBinder binder)
        {
            var xilsi = instr.CreateStk(new InstructionDependency[0], operandTypes, resultTypes);

            IXILMapping mapping;

            if (_xilMappings.TryGetValue(xilsi, out mapping))
            {
                return(mapping);
            }
            IEnumerable <IXILMapper> mappers = _xmm.LookupMappers(instr);

            foreach (IXILMapper mapper in mappers)
            {
                var tas = _taMapLookup.Get(mapper);
                foreach (var ta in tas)
                {
                    var mappings = mapper.TryMap(ta, instr, operandTypes, resultTypes);
                    if (mappings.Any())
                    {
                        mapping             = mappings.First();
                        _xilMappings[xilsi] = mapping;
                        return(mapping);
                    }
                }
            }
            foreach (IXILMapper mapper in mappers)
            {
                mapping = mapper.TryAllocate(_host, instr, operandTypes, resultTypes, _targetProject);
                if (mapping != null)
                {
                    _taMapLookup.Add(mapper, mapping.TASite);
                    _xilMappings[xilsi] = mapping;
                    return(mapping);
                }
            }
            return(null);
        }
Example #11
0
        /// <summary>
        /// Returns a sequence of adminissible result types, given instruction operand types.
        /// </summary>
        /// <param name="instr">XIL instruction</param>
        /// <param name="operandTypes">operand types</param>
        /// <returns>admissible result types</returns>
        public static IEnumerable <TypeDescriptor> GetDefaultResultTypes(this XILInstr instr, TypeDescriptor[] operandTypes)
        {
            switch (instr.Name)
            {
            case InstructionCodes.Abs:
                if (operandTypes[0].CILType.Equals(typeof(float)) ||
                    operandTypes[0].CILType.Equals(typeof(double)) ||
                    operandTypes[0].CILType.Equals(typeof(int)) ||
                    operandTypes[0].CILType.Equals(typeof(long)) ||
                    operandTypes[0].CILType.Equals(typeof(sbyte)) ||
                    operandTypes[0].CILType.Equals(typeof(short)))
                {
                    yield return(operandTypes[0]);
                }
                else if (operandTypes[0].CILType.Equals(typeof(double)))
                {
                    yield return(typeof(double));
                }
                else if (operandTypes[0].CILType.Equals(typeof(SFix)))
                {
                    var fmt     = SFix.GetFormat(operandTypes[0]);
                    var ssample = SFix.FromDouble(0.0, fmt.IntWidth + 1, fmt.FracWidth);
                    yield return(TypeDescriptor.GetTypeOf(ssample));

                    var usample = UFix.FromDouble(0.0, fmt.IntWidth, fmt.FracWidth);
                    yield return(TypeDescriptor.GetTypeOf(usample));
                }
                else if (operandTypes[0].CILType.Equals(typeof(UFix)))
                {
                    yield return(operandTypes[0]);
                }
                else
                {
                    throw new NotSupportedException("Operand type not supported");
                }
                break;

            case InstructionCodes.Add:
            {
                dynamic o1 = operandTypes[0].GetSampleInstance();
                dynamic o2 = operandTypes[1].GetSampleInstance();
                object  r  = o1 + o2;
                yield return(TypeDescriptor.GetTypeOf(r));
            }
            break;

            case InstructionCodes.And:
            {
                dynamic o1 = operandTypes[0].GetSampleInstance();
                dynamic o2 = operandTypes[1].GetSampleInstance();
                object  r  = o1 & o2;
                yield return(TypeDescriptor.GetTypeOf(r));
            }
            break;

            case InstructionCodes.Barrier:
            case InstructionCodes.BranchIfFalse:
            case InstructionCodes.BranchIfTrue:
                yield break;

            case InstructionCodes.Ceil:
            case InstructionCodes.Floor:
            case InstructionCodes.SinCos:
                if (operandTypes[0].CILType.Equals(typeof(float)) ||
                    operandTypes[0].CILType.Equals(typeof(double)))
                {
                    yield return(operandTypes[0]);
                }
                else
                {
                    throw new NotSupportedException();
                }
                break;

            case InstructionCodes.Cos:
            case InstructionCodes.Sin:
                if (operandTypes[0].CILType.Equals(typeof(float)) ||
                    operandTypes[0].CILType.Equals(typeof(double)))
                {
                    yield return(operandTypes[0]);
                }
                else if (operandTypes[0].CILType.Equals(typeof(UFix)) ||
                         operandTypes[0].CILType.Equals(typeof(SFix)))
                {
                    var fmt = operandTypes[0].GetFixFormat();
                    // computation works for at most 26 fractional bits
                    double xinc = Math.Pow(2.0, Math.Max(-26, -fmt.FracWidth));
                    double yinc = 1.0 - Math.Cos(xinc);
                    int    fw   = -MathExt.FloorLog2(yinc);
                    // Xilinx Cordic doesn't like more than 48 result bits
                    if (fw > 48)
                    {
                        fw = 48;
                    }
                    while (fw >= 0)
                    {
                        yield return(SFix.MakeType(2, fw));

                        --fw;
                    }
                }
                else
                {
                    throw new NotSupportedException();
                }
                break;

            case InstructionCodes.ScSin:
            case InstructionCodes.ScCos:
            case InstructionCodes.ScSinCos:
                if (operandTypes[0].CILType.Equals(typeof(float)) ||
                    operandTypes[0].CILType.Equals(typeof(double)))
                {
                    yield return(operandTypes[0]);
                }
                else if (operandTypes[0].CILType.Equals(typeof(UFix)) ||
                         operandTypes[0].CILType.Equals(typeof(SFix)))
                {
                    var fmt = operandTypes[0].GetFixFormat();
                    // computation works for at most 26 fractional bits
                    double xinc = Math.Pow(2.0, Math.Max(-26, -fmt.FracWidth));
                    double yinc = 1.0 - Math.Cos(xinc);
                    int    fw   = -MathExt.FloorLog2(yinc);
                    // Xilinx Cordic doesn't like more than 48 result bits
                    if (fw > 48)
                    {
                        fw = 48;
                    }
                    while (fw >= 0)
                    {
                        yield return(SFix.MakeType(2, fw));

                        --fw;
                    }
                }
                else
                {
                    throw new NotSupportedException();
                }
                break;

            case InstructionCodes.Sqrt:
                if (operandTypes[0].CILType.Equals(typeof(float)) ||
                    operandTypes[0].CILType.Equals(typeof(double)))
                {
                    yield return(operandTypes[0]);
                }
                else if (operandTypes[0].CILType.Equals(typeof(UFix)))
                {
                    var fmt = UFix.GetFormat(operandTypes[0]);
                    int iw  = (fmt.IntWidth + 1) / 2;
                    yield return(UFix.MakeType(iw, fmt.TotalWidth - iw));
                }
                else if (operandTypes[0].CILType.Equals(typeof(SFix)))
                {
                    var fmt = SFix.GetFormat(operandTypes[0]);
                    int iw  = fmt.IntWidth / 2;
                    yield return(UFix.MakeType(iw, fmt.TotalWidth - iw - 1));
                }
                else if (operandTypes[0].CILType.Equals(typeof(Unsigned)))
                {
                    var fmt = UFix.GetFormat(operandTypes[0]);
                    int iw  = (fmt.IntWidth + 1) / 2;
                    yield return(Unsigned.MakeType(iw));
                }
                else if (operandTypes[0].CILType.Equals(typeof(Signed)))
                {
                    var fmt = SFix.GetFormat(operandTypes[0]);
                    int iw  = fmt.IntWidth / 2;
                    yield return(Unsigned.MakeType(iw));
                }
                else
                {
                    throw new NotImplementedException();
                }
                break;

            case InstructionCodes.Cmp:
                throw new NotImplementedException();

            case InstructionCodes.Concat:
            {
                var v1 = (StdLogicVector)operandTypes[0].GetSampleInstance();
                var v2 = (StdLogicVector)operandTypes[1].GetSampleInstance();
                var c  = v1.Concat(v2);
                yield return(TypeDescriptor.GetTypeOf(c));
            }
            break;

            case InstructionCodes.Convert:
                throw new NotImplementedException();

            case InstructionCodes.Dig:
            case InstructionCodes.Dup:
            case InstructionCodes.Swap:
                throw new NotSupportedException();

            case InstructionCodes.Div:
            {
                dynamic o1 = operandTypes[0].GetSampleInstance();
                dynamic o2 = operandTypes[1].GetSampleInstance(ETypeCreationOptions.NonZero);
                object  r  = o1 / o2;
                yield return(TypeDescriptor.GetTypeOf(r));
            }
            break;

            case InstructionCodes.ExitMarshal:
            case InstructionCodes.Goto:
            case InstructionCodes.Nop:
            case InstructionCodes.Pop:
            case InstructionCodes.Return:
            case InstructionCodes.StelemFixA:
            case InstructionCodes.StelemFixAFixI:
            case InstructionCodes.StoreVar:
            case InstructionCodes.WrMem:
            case InstructionCodes.WrMemFix:
            case InstructionCodes.WrPort:
                yield break;

            case InstructionCodes.Mod2:
            {
                var fmt = operandTypes[0].GetFixFormat();
                if (fmt == null)
                {
                    throw new NotSupportedException("mod2 is only supported for fixed-point types");
                }

                for (int iw = 2; iw <= fmt.IntWidth; iw++)
                {
                    yield return(new FixFormat(fmt.IsSigned, iw, fmt.FracWidth).ToType());
                }
            }
            break;

            case InstructionCodes.DivQF:
            case InstructionCodes.ExtendSign:
            case InstructionCodes.Ld0:
            case InstructionCodes.LdelemFixA:
            case InstructionCodes.LdelemFixAFixI:
            case InstructionCodes.LdMemBase:
            case InstructionCodes.LShift:
            case InstructionCodes.RdMem:
            case InstructionCodes.RdMemFix:
            case InstructionCodes.RShift:
            case InstructionCodes.Sign:
            case InstructionCodes.SliceFixI:
                throw new NotImplementedException();

            case InstructionCodes.IsEq:
            case InstructionCodes.IsGt:
            case InstructionCodes.IsGte:
            case InstructionCodes.IsLt:
            case InstructionCodes.IsLte:
            case InstructionCodes.IsNEq:
                yield return(typeof(bool));

                break;

            case InstructionCodes.LdConst:
                yield return(TypeDescriptor.GetTypeOf(instr.Operand));

                break;

            case InstructionCodes.LoadVar:
            {
                var lit = (IStorableLiteral)instr.Operand;
                yield return(lit.Type);
            }
            break;

            case InstructionCodes.Max:
            case InstructionCodes.Min:
                yield return(operandTypes[0]);

                break;

            case InstructionCodes.Mul:
            {
                dynamic o1 = operandTypes[0].GetSampleInstance();
                dynamic o2 = operandTypes[1].GetSampleInstance();
                object  r  = o1 * o2;
                yield return(TypeDescriptor.GetTypeOf(r));
            }
            break;

            case InstructionCodes.Neg:
            {
                dynamic o1 = operandTypes[0].GetSampleInstance();
                object  r  = -o1;
                yield return(TypeDescriptor.GetTypeOf(r));
            }
            break;

            case InstructionCodes.Not:
            {
                dynamic o1 = operandTypes[0].GetSampleInstance();
                object  r  = !o1;
                yield return(TypeDescriptor.GetTypeOf(r));
            }
            break;

            case InstructionCodes.Or:
            {
                dynamic o1 = operandTypes[0].GetSampleInstance();
                dynamic o2 = operandTypes[1].GetSampleInstance();
                object  r  = o1 | o2;
                yield return(TypeDescriptor.GetTypeOf(r));
            }
            break;

            case InstructionCodes.RdPort:
            {
                var port = (ISignalOrPortDescriptor)instr.Operand;
                yield return(port.ElementType);
            }
            break;

            case InstructionCodes.Rem:
            {
                dynamic o1 = operandTypes[0].GetSampleInstance();
                dynamic o2 = operandTypes[1].GetSampleInstance(ETypeCreationOptions.NonZero);
                object  r  = o1 % o2;
                yield return(TypeDescriptor.GetTypeOf(r));
            }
            break;

            case InstructionCodes.Rempow2:
            {
                dynamic o1 = operandTypes[0].GetSampleInstance();
                int     n  = (int)instr.Operand;
                object  r  = MathExt.Rempow2((dynamic)o1, n);
                yield return(TypeDescriptor.GetTypeOf(r));
            }
            break;

            case InstructionCodes.Select:
                yield return(operandTypes[1]);

                break;

            case InstructionCodes.Slice:
                yield return(typeof(StdLogicVector));

                break;

            case InstructionCodes.Sub:
            {
                dynamic o1 = operandTypes[0].GetSampleInstance();
                dynamic o2 = operandTypes[1].GetSampleInstance();
                object  r  = o1 - o2;
                yield return(TypeDescriptor.GetTypeOf(r));
            }
            break;

            case InstructionCodes.Xor:
            {
                dynamic o1 = operandTypes[0].GetSampleInstance();
                dynamic o2 = operandTypes[1].GetSampleInstance();
                object  r  = o1 ^ o2;
                yield return(TypeDescriptor.GetTypeOf(r));
            }
            break;

            default:
                throw new NotImplementedException();
            }
        }
Example #12
0
        public IEnumerable <IXILMapping> TryMap(ITransactionSite taSite, XILInstr instr, TypeDescriptor[] operandTypes, TypeDescriptor[] resultTypes)
        {
            var mappers = _mlookup.Get(instr.Name);

            return(mappers.SelectMany(m => m.TryMap(taSite, instr, operandTypes, resultTypes)));
        }
Example #13
0
 public IEnumerable <IXILMapper> LookupMappers(XILInstr instr)
 {
     return(_mlookup.Get(instr.Name));
 }
Example #14
0
 public ClassifyCookie(XILInstr instr)
 {
     Contract.Requires(instr != null);
     _instr = instr;
 }
Example #15
0
        private XIL3Function Run()
        {
            List <XIL3Instr>   xil3is  = new List <XIL3Instr>();
            List <BranchLabel> targets = new List <BranchLabel>();

            foreach (XILSInstr xilsi in _func.Instructions)
            {
                switch (xilsi.Name)
                {
                case InstructionCodes.Pop:
                    _stack.Pop();
                    break;

                case InstructionCodes.Dup:
                    _stack.Push(_stack.Peek());
                    break;

                case InstructionCodes.Swap:
                {
                    int a = _stack.Pop();
                    int b = _stack.Pop();
                    _stack.Push(a);
                    _stack.Push(b);
                }
                break;

                case InstructionCodes.Dig:
                {
                    int         pos      = (int)xilsi.StaticOperand;
                    Stack <int> tmpStack = new Stack <int>();
                    for (int i = 0; i < pos; i++)
                    {
                        tmpStack.Push(_stack.Pop());
                    }
                    int dig = _stack.Pop();
                    for (int i = 0; i < pos; i++)
                    {
                        _stack.Push(tmpStack.Pop());
                    }
                    _stack.Push(dig);
                }
                break;

                default:
                {
                    int[] oslots, rslots;
                    InstructionDependency[] preds;
                    Remap(xilsi, out preds, out oslots, out rslots);
                    XIL3Instr xil3i;
                    switch (xilsi.Name)
                    {
                    case InstructionCodes.Goto:
                    case InstructionCodes.BranchIfFalse:
                    case InstructionCodes.BranchIfTrue:
                    {
                        BranchLabel orgTarget = (BranchLabel)xilsi.StaticOperand;
                        BranchLabel target    = new BranchLabel()
                        {
                            InstructionIndex = orgTarget.InstructionIndex
                        };
                        targets.Add(target);
                        xil3i = new XILInstr(xilsi.Name, target).Create3AC(preds, oslots, rslots);
                    }
                    break;

                    default:
                        xil3i = xilsi.Command.Create3AC(preds, oslots, rslots);
                        break;
                    }
                    xil3i.Index  = xil3is.Count;
                    xil3i.CILRef = xilsi.CILRef;
                    xil3is.Add(xil3i);
                    _indexMap[xilsi.Index] = xil3i.Index;
                }
                break;
                }
            }
            foreach (BranchLabel target in targets)
            {
                target.InstructionIndex = _indexMap[target.InstructionIndex];
            }
            return(new XIL3Function(_func.Name, _func.Arguments, _func.Locals, xil3is.ToArray(), _slotTypes.ToArray()));
        }