예제 #1
0
        public override bool Rewrite(CodeDescriptor decompilee, MethodBase callee, StackElement[] args, IDecompiler stack, IFunctionBuilder builder)
        {
            var stateLookup = stack.QueryAttribute <IStateLookup>();

            if (stateLookup == null)
            {
                var pd = decompilee as ProcessDescriptor;
                if (pd == null)
                {
                    var md = decompilee as MethodDescriptor;
                    if (md == null)
                    {
                        throw new InvalidOperationException("Unsupported code descriptor: " + decompilee);
                    }
                    pd = md.CallingProcess;
                }
                var pred     = pd.Instance.Predicate;
                var predElem = stack.GetCallExpression(
                    pred.Method, new StackElement(LiteralReference.CreateConstant(pred.Target), pred.Target, EVariability.Constant));
                var fspec = new FunctionSpec(typeof(void))
                {
                    CILRep       = callee,
                    IntrinsicRep = IntrinsicFunctions.Wait(WaitParams.EWaitKind.WaitUntil)
                };
                builder.Call(fspec, new Expression[] { predElem.Expr });
            }
            else
            {
                builder.Store(
                    stateLookup.NextStateSignal,
                    stateLookup.GetStateExpression(stack.CurrentILIndex));
                builder.Return();
            }
            return(true);
        }
예제 #2
0
            protected override void DeclareAlgorithm()
            {
                var        srClk = SignalRef.Create(_taSite._clk, SignalRef.EReferencedProperty.RisingEdge);
                var        lrClk = new LiteralReference(srClk);
                var        srEn  = SignalRef.Create(_taSite._en, SignalRef.EReferencedProperty.Cur);
                var        lrEn  = new LiteralReference(srEn);
                var        lr1   = LiteralReference.CreateConstant(StdLogic._1);
                var        cond  = lrClk & (Expression.Equal(lrEn, lr1));
                var        srSLV = SignalRef.Create(_taSite._slvSignal, SignalRef.EReferencedProperty.Cur);
                var        lrSLV = new LiteralReference(srSLV);
                Expression conv;

                if (_taSite._port.InitialValue.GetType().Equals(typeof(StdLogicVector)))
                {
                    conv = lrSLV;
                }
                else
                {
                    conv = IntrinsicFunctions.Cast(
                        lrSLV,
                        typeof(StdLogicVector),
                        TypeDescriptor.GetTypeOf(_taSite._port.InitialValue));
                }
                var srNext = SignalRef.Create(_taSite._port, SignalRef.EReferencedProperty.Next);

                If(cond);
                {
                    Store(srNext, conv);
                }
                EndIf();
            }
예제 #3
0
            public override bool Rewrite(
                CodeDescriptor decompilee,
                Expression waitObject,
                Analysis.IDecompiler stack,
                IFunctionBuilder builder)
            {
                var fspec = new FunctionSpec(typeof(void))
                {
                    IntrinsicRep = IntrinsicFunctions.Wait(WaitParams.EWaitKind.WaitFor)
                };

                builder.Call(fspec, waitObject);
                return(true);
            }
예제 #4
0
        private Expression MakeIntegerResult(Expression ex)
        {
            var arg = ex.Accept(this);

            if (arg.ResultType.CILType.Equals(typeof(int)))
            {
                return(arg);
            }
            else
            {
                var iarg = IntrinsicFunctions.Cast(ex, arg.ResultType.CILType, typeof(int));
                return(iarg);
            }
        }
예제 #5
0
        private void MakeStringArray(Expression[] elements)
        {
            TypeDescriptor stype = (TypeDescriptor)typeof(string);

            for (int i = 0; i < elements.Length; i++)
            {
                TypeDescriptor rtype = elements[i].ResultType;
                if (!rtype.Equals(stype))
                {
                    elements[i] = IntrinsicFunctions.Cast(
                        elements[i],
                        rtype.CILType, typeof(string));
                }
            }
        }
예제 #6
0
            public override bool Rewrite(Meta.CodeDescriptor decompilee, System.Reflection.MethodBase callee, Analysis.StackElement[] args, Analysis.IDecompiler stack, IFunctionBuilder builder)
            {
                object[] outArgs;
                object   sample;

                if (!stack.TryGetReturnValueSample((MethodInfo)callee, args, out outArgs, out sample))
                {
                    throw new InvalidOperationException("Unable to create sample for ScSinCos call");
                }

                var fcall = IntrinsicFunctions.XILOpCode(
                    new XILInstr(InstructionCodes.ScSinCos),
                    TypeDescriptor.GetTypeOf(sample),
                    new Expression[] { args[0].Expr });

                stack.Push(fcall, sample);
                return(true);
            }
예제 #7
0
 public override bool Rewrite(CodeDescriptor decompilee, MethodBase callee, StackElement[] args,
                              IDecompiler decomp, IFunctionBuilder builder)
 {
     Expression[] elements = null;
     if (args.Length == 1)
     {
         Expression valarr = args[0].Expr;
         valarr = decomp.ResolveVariableReference(decomp.CurrentILIndex, valarr);
         FunctionCall newarrCall = valarr as FunctionCall;
         if (newarrCall != null)
         {
             FunctionSpec      fspec = newarrCall.Callee as FunctionSpec;
             IntrinsicFunction ifun  = fspec == null ? null : fspec.IntrinsicRep;
             if (ifun != null && ifun.Action == IntrinsicFunction.EAction.NewArray)
             {
                 ArrayParams aparams = (ArrayParams)ifun.Parameter;
                 if (aparams.IsStatic)
                 {
                     newarrCall.IsInlined = true;
                     for (int i = 0; i < aparams.Elements.Length; i++)
                     {
                         aparams.Elements[i].IsInlined = true;
                     }
                     elements = aparams.Elements;
                 }
             }
         }
     }
     else
     {
         elements = args.Select(arg => arg.Expr).ToArray();
     }
     if (elements == null)
     {
         throw new NotImplementedException();
     }
     MakeStringArray(elements);
     decomp.Push(
         IntrinsicFunctions.StringConcat(elements),
         "");
     return(true);
 }
예제 #8
0
            public override bool Rewrite(CodeDescriptor decompilee, System.Reflection.MethodBase callee, Analysis.StackElement[] args, Analysis.IDecompiler stack, IFunctionBuilder builder)
            {
                Array arr = (Array)args[0].Sample;

                if (arr == null)
                {
                    throw new InvalidOperationException("Unable to deduce array length");
                }

                int  numElems = arr.Length;
                Type tTE      = arr.GetType().GetElementType();
                Type tTA;

                callee.IsFunction(out tTA);
                FunctionCall      newCall = IntrinsicFunctions.NewArray(tTE, LiteralReference.CreateConstant(numElems), arr);
                FunctionSpec      fspec   = (FunctionSpec)newCall.Callee;
                IntrinsicFunction ifun    = fspec.IntrinsicRep;
                ArrayParams       aparams = (ArrayParams)ifun.Parameter;

                for (int i = 0; i < numElems; i++)
                {
                    aparams.Elements[i] = IntrinsicFunctions.GetArrayElement(
                        args[0].Expr,
                        LiteralReference.CreateConstant(i));
                }

                object sample = null;

                try
                {
                    sample = callee.Invoke(arr);
                }
                catch (Exception)
                {
                }

                Expression conv = IntrinsicFunctions.Cast(newCall, arr.GetType(), tTA);

                stack.Push(conv, sample);
                return(true);
            }
예제 #9
0
            public override bool Rewrite(Meta.CodeDescriptor decompilee, SysDOM.Expression waitObject, Analysis.IDecompiler stack, SysDOM.IFunctionBuilder builder)
            {
                var evt    = waitObject.ResultType.GetSampleInstance();
                var sevent = evt as Event;

                if (sevent == null)
                {
                    // This workaround is for the following situation:
                    //   Signal s;
                    //   await s;
                    // This will actually await the "changed event" which is associated with the signal. However, decompilation
                    // will treat the signal instance as the awaited object and pass a Signal instance instead of the event.
                    // The code will try to restore the Event instance from the Awaiter.
                    Awaiter awaiter = null;
                    try
                    {
                        awaiter = ((object)AwaitableExtensionMethods.GetAwaiter((dynamic)evt)) as Awaiter;
                    }
                    catch
                    {
                    }
                    if (awaiter == null)
                    {
                        throw new InvalidOperationException("Unable to resolve awaited MultiEvent");
                    }
                    sevent = awaiter._event;
                }

                var signal    = (SignalBase)sevent.Owner;
                var signalRef = SignalRef.Create(signal, SignalRef.EReferencedProperty.Instance);
                var arg       = (LiteralReference)signalRef;

                var fspec = new FunctionSpec(typeof(void))
                {
                    IntrinsicRep = IntrinsicFunctions.Wait(WaitParams.EWaitKind.WaitOn)
                };

                builder.Call(fspec, arg);
                return(true);
            }
예제 #10
0
        public override bool Rewrite(CodeDescriptor decompilee, MethodBase callee, StackElement[] args, IDecompiler stack, IFunctionBuilder builder)
        {
            if (args[0].Sample == null)
            {
                return(false);
            }

            ISized one, rsample;

            if (IsSigned)
            {
                Signed sample = (Signed)args[0].Sample;
                Signed sone   = Signed.FromLong(1, (int)sample.Size);
                one     = sone;
                rsample = sample + sone;
            }
            else
            {
                Unsigned sample = (Unsigned)args[0].Sample;
                Unsigned uone   = Unsigned.FromULong(1, (int)sample.Size);
                one     = uone;
                rsample = sample + uone;
            }
            LiteralReference oneLit = LiteralReference.CreateConstant(one);
            Expression       inc;

            if (IsDecrement)
            {
                inc = args[0].Expr - oneLit;
            }
            else
            {
                inc = args[0].Expr + oneLit;
            }
            inc.ResultType = TypeDescriptor.GetTypeOf(rsample);
            inc            = IntrinsicFunctions.Resize(inc, (int)one.Size, TypeDescriptor.GetTypeOf(one));
            stack.Push(new StackElement(inc, one, Analysis.Msil.EVariability.ExternVariable));
            return(true);
        }
예제 #11
0
            public override bool Rewrite(Meta.CodeDescriptor decompilee, SysDOM.Expression waitObject, Analysis.IDecompiler stack, SysDOM.IFunctionBuilder builder)
            {
                var evt    = waitObject.ResultType.GetSampleInstance();
                var mevent = evt as MultiEvent;

                if (mevent == null)
                {
                    throw new InvalidOperationException("Unable to resolve awaited MultiEvent");
                }

                var events     = mevent._events.Cast <Event>();
                var signals    = events.Select(e => (SignalBase)e.Owner);
                var signalRefs = signals.Select(s => SignalRef.Create(s, SignalRef.EReferencedProperty.Instance));
                var args       = signalRefs.Select(sr => (LiteralReference)sr).ToArray();

                var fspec = new FunctionSpec(typeof(void))
                {
                    IntrinsicRep = IntrinsicFunctions.Wait(WaitParams.EWaitKind.WaitOn)
                };

                builder.Call(fspec, args);
                return(true);
            }
예제 #12
0
            public override bool Rewrite(Meta.CodeDescriptor decompilee, SysDOM.Expression waitObject, Analysis.IDecompiler stack, SysDOM.IFunctionBuilder builder)
            {
                var evt     = waitObject.ResultType.GetSampleInstance();
                var peevent = evt as PredicatedEvent;

                if (peevent == null)
                {
                    throw new InvalidOperationException("Unable to resolve awaited PredicatedEvent");
                }

                var pred = peevent._pred;
                var rwc  = pred.Method.GetCustomOrInjectedAttribute <RewriteCall>();

                if (rwc == null)
                {
                    throw new InvalidOperationException("Awaited predicate is not synthesizable.");
                }

                var lr   = LiteralReference.CreateConstant(pred.Target);
                var se   = new StackElement(lr, pred.Target, Analysis.Msil.EVariability.Constant);
                var pstk = stack.CreatePrivateStack();

                if (!rwc.Rewrite(decompilee, pred.Method, new StackElement[] { se }, pstk, builder))
                {
                    throw new InvalidOperationException("Unable to implement awaited predicate.");
                }

                var predEx = pstk.Pop();
                var fspec  = new FunctionSpec(typeof(void))
                {
                    IntrinsicRep = IntrinsicFunctions.Wait(WaitParams.EWaitKind.WaitUntil)
                };

                builder.Call(fspec, predEx.Expr);

                return(true);
            }
예제 #13
0
            protected override void DeclareAlgorithm()
            {
                var srCur = SignalRef.Create(_taSite._portSignal, SignalRef.EReferencedProperty.Cur);
                var lrCur = new LiteralReference(srCur);

                if (_taSite._portSignal.ElementType.CILType.Equals(typeof(StdLogic)))
                {
                    var index = new IndexSpec((DimSpec)0);
                    var srSLV = new SignalRef(
                        _taSite._slvSignal,
                        SignalRef.EReferencedProperty.Next,
                        index.AsExpressions(),
                        index, true);
                    Store(srSLV, lrCur);
                }
                else
                {
                    var convFn = IntrinsicFunctions.Cast(lrCur,
                                                         _taSite._portSignal.ElementType.CILType,
                                                         _taSite._slvSignal.ElementType);
                    var srSLV = SignalRef.Create(_taSite._slvSignal, SignalRef.EReferencedProperty.Next);
                    Store(srSLV, convFn);
                }
            }
예제 #14
0
                protected override void DeclareAlgorithm()
                {
                    var srClk      = SignalRef.Create(_taSite._clk, SignalRef.EReferencedProperty.RisingEdge);
                    var lrClk      = new LiteralReference(srClk);
                    var srWrEn     = _taSite.NeedWriteAccess ? SignalRef.Create(_taSite._wrEn, SignalRef.EReferencedProperty.Cur) : null;
                    var lrWrEn     = _taSite.NeedWriteAccess ? new LiteralReference(srWrEn) : null;
                    var srAddr     = SignalRef.Create(_taSite._addr, SignalRef.EReferencedProperty.Cur);
                    var lrAddr     = new LiteralReference(srAddr);
                    var srDataIn   = _taSite.NeedWriteAccess ? SignalRef.Create(_taSite._dataIn, SignalRef.EReferencedProperty.Cur) : null;
                    var lrDataIn   = _taSite.NeedWriteAccess ? new LiteralReference(srDataIn) : null;
                    var srDataOut  = SignalRef.Create(_taSite._dataOut, SignalRef.EReferencedProperty.Next);
                    var hi         = LiteralReference.CreateConstant(StdLogic._1);
                    var addrUType  = TypeDescriptor.GetTypeOf(((StdLogicVector)_taSite._addr.InitialValue).UnsignedValue);
                    var uAddr      = IntrinsicFunctions.Cast(lrAddr, typeof(StdLogicVector), addrUType);
                    var iAddr      = IntrinsicFunctions.Cast(uAddr, addrUType.CILType, typeof(int));
                    var array      = _taSite._array;
                    var lrArray    = new LiteralReference(array.ArrayLit);
                    var elemType   = array.ElementType;
                    var aref       = new ArrayRef(lrArray, elemType, iAddr);
                    var convDataIn = _taSite.NeedWriteAccess ? IntrinsicFunctions.Cast(lrDataIn, typeof(StdLogicVector), elemType) : null;
                    var convAref   = IntrinsicFunctions.Cast(aref, elemType.CILType, _taSite._dataOut.ElementType);

                    If(lrClk);
                    {
                        Store(srDataOut, convAref);
                        if (_taSite.NeedWriteAccess)
                        {
                            If(Expression.Equal(lrWrEn, hi));
                            {
                                Store(aref, convDataIn);
                            }
                            EndIf();
                        }
                    }
                    EndIf();
                }
예제 #15
0
        public override bool Rewrite(CodeDescriptor decompilee, Expression waitObject, IDecompiler stack, IFunctionBuilder builder)
        {
            if (stack.HasAttribute <Analysis.M2M.HLS>())
            {
                return(true);
            }

            var       curps = DesignContext.Instance.CurrentProcess;
            SLSignal  clk   = (SLSignal)curps.Sensitivity[0].Owner;
            SignalRef srEdge;

            if (curps.Predicate.Equals((Func <bool>)clk.RisingEdge))
            {
                srEdge = SignalRef.Create(clk.Descriptor, SignalRef.EReferencedProperty.RisingEdge);
            }
            else
            {
                srEdge = SignalRef.Create(clk.Descriptor, SignalRef.EReferencedProperty.FallingEdge);
            }
            var lrEdge = new LiteralReference(srEdge);

            int  nwait      = 0;
            var  nwaitEx    = waitObject.Children[0];
            bool nwaitConst = nwaitEx.IsConst();

            if (nwaitConst)
            {
                nwait = (int)TypeConversions.ConvertValue(
                    nwaitEx.Eval(DefaultEvaluator.DefaultConstEvaluator),
                    typeof(int));
            }

            var fspec = new FunctionSpec(typeof(void))
            {
                IntrinsicRep = IntrinsicFunctions.Wait(WaitParams.EWaitKind.WaitUntil)
            };

            Variable         v   = null;
            LiteralReference lrV = null;

            if (!nwaitConst || nwait > 3)
            {
                v = new Variable(typeof(int))
                {
                    Name = "_wait_i" + (ictr++)
                };
                builder.DeclareLocal(v);
                lrV = new LiteralReference(v);
                builder.Store(v, LiteralReference.CreateConstant((int)0));
                var loop = builder.Loop();
                builder.If(Expression.Equal(lrV, nwaitEx));
                {
                    builder.Break(loop);
                }
                builder.EndIf();
            }
            int ncalls = 1;

            if (nwaitConst && nwait <= 3)
            {
                ncalls = nwait;
            }
            for (int i = 0; i < ncalls; i++)
            {
                builder.Call(fspec, lrEdge);
            }
            if (!nwaitConst || nwait > 3)
            {
                builder.Store(v, lrV + LiteralReference.CreateConstant((int)1));
                builder.EndLoop();
            }
            return(true);
        }
예제 #16
0
                public void AddAccessor(InlineFieldMapperTransactionSite taSite, bool needRead, bool needWrite)
                {
                    var  srWrEn     = needWrite ? SignalRef.Create(taSite._wrEn, SignalRef.EReferencedProperty.Cur) : null;
                    var  lrWrEn     = needWrite ? new LiteralReference(srWrEn) : null;
                    var  srDataIn   = needWrite ? SignalRef.Create(taSite._dataIn, SignalRef.EReferencedProperty.Cur) : null;
                    var  lrDataIn   = needWrite ? new LiteralReference(srDataIn) : null;
                    var  srDataOut  = needRead ? SignalRef.Create(taSite._dataOut, SignalRef.EReferencedProperty.Next) : null;
                    var  hi         = LiteralReference.CreateConstant(StdLogic._1);
                    var  elemType   = taSite._literal.Type;
                    var  lrVar      = new LiteralReference((Literal)taSite._literal);
                    var  convDataIn = needWrite ? IntrinsicFunctions.Cast(lrDataIn, typeof(StdLogicVector), elemType) : null;
                    var  convVar    = needRead ? IntrinsicFunctions.Cast(lrVar, elemType.CILType, taSite._dataOut.ElementType) : null;
                    bool isBool     = taSite._literal.Type.CILType.Equals(typeof(bool));
                    var  lr1        = LiteralReference.CreateConstant((StdLogicVector)"1");
                    var  lr0        = LiteralReference.CreateConstant((StdLogicVector)"0");

                    if (needWrite)
                    {
                        BodyBuilder.If(Expression.Equal(lrWrEn, hi));
                        {
                            if (isBool)
                            {
                                BodyBuilder.Store(taSite._literal, Expression.Equal(lrDataIn, lr1));
                            }
                            else
                            {
                                BodyBuilder.Store(taSite._literal, convDataIn);
                            }

                            var diagOut = taSite.Host as ISupportsDiagnosticOutput;
                            if (diagOut != null && diagOut.EnableDiagnostics)
                            {
                                Expression vref  = new LiteralReference(taSite.Literal);
                                var        fref  = taSite.Literal as FieldRef;
                                var        field = fref != null ? fref.FieldDesc : null;
                                if (field != null && field.HasAttribute <ActualTypeAttribute>())
                                {
                                    var atype = field.QueryAttribute <ActualTypeAttribute>();
                                    vref = IntrinsicFunctions.Cast(vref, vref.ResultType.CILType, atype.ActualType, true);
                                }
                                BodyBuilder.ReportLine(taSite.Literal.Name + " changed to ", vref);
                            }
                        }
                        BodyBuilder.EndIf();
                    }
                    if (needRead)
                    {
                        if (isBool)
                        {
                            BodyBuilder.If(lrVar);
                            {
                                BodyBuilder.If(lrVar);
                                BodyBuilder.Store(srDataOut, lr1);
                            }
                            BodyBuilder.Else();
                            {
                                BodyBuilder.Store(srDataOut, lr0);
                            }
                            BodyBuilder.EndIf();
                        }
                        else
                        {
                            BodyBuilder.Store(srDataOut, convVar);
                        }
                    }
                }