Esempio n. 1
0
        public Identifier VisitSequenceStorage(SequenceStorage seq)
        {
            var dt     = this.dt !;
            var clones = seq.Elements.Select(e => e.Accept(this).Storage);

            return(procCalling.Frame.EnsureSequence(dt, clones.ToArray()));
        }
Esempio n. 2
0
        public Identifier VisitSequenceStorage(SequenceStorage seq)
        {
            var idSeq    = id;
            var newElems = seq.Elements.Select(e => e.Accept(this).Storage);

            return(frame.EnsureSequence(idSeq.DataType, newElems.ToArray()));
        }
Esempio n. 3
0
        public void MspRealModeServices()
        {
            IntelArchitecture arch     = new IntelArchitecture(ProcessorMode.Real);
            Platform          platform = new MsdosPlatform(null, arch);

            var state = arch.CreateProcessorState();

            state.SetRegister(Registers.ah, Constant.Byte(0x3E));
            SystemService svc = platform.FindService(0x21, state);

            Assert.AreEqual("msdos_close_file", svc.Name);
            Assert.AreEqual(1, svc.Signature.Parameters.Length);
            Assert.IsFalse(svc.Characteristics.Terminates, "close() shouldn't terminate program");

            state.SetRegister(Registers.ah, Constant.Byte(0x4C));
            svc = platform.FindService(0x21, state);
            Assert.AreEqual("msdos_terminate", svc.Name);
            Assert.AreEqual(1, svc.Signature.Parameters.Length);
            Assert.IsTrue(svc.Characteristics.Terminates, "terminate() should terminate program");

            state.SetRegister(Registers.ah, Constant.Byte(0x2F));
            svc = platform.FindService(0x21, state);
            Assert.AreEqual("msdos_get_disk_transfer_area_address", svc.Name);
            Assert.AreEqual(0, svc.Signature.Parameters.Length);
            SequenceStorage seq = (SequenceStorage)svc.Signature.ReturnValue.Storage;

            Assert.AreEqual("es", seq.Head.Name);
            Assert.AreEqual("bx", seq.Tail.Name);
        }
Esempio n. 4
0
        public void UrfXXX()
        {
            var sExp    = "Used: [0..31]";
            var regDx   = new RegisterStorage("dx", 2, 0, PrimitiveType.Word16);
            var regAx   = new RegisterStorage("ax", 0, 0, PrimitiveType.Word16);
            var seqDxAx = new SequenceStorage(regDx, regAx);

            RunClassifyTest(
                sExp,
                "dx_ax",
                m =>
            {
                var ax    = m.Reg("dx", regAx);
                var dx    = m.Reg("ax", regDx);
                var dx_ax = m.SeqId("dx_ax", PrimitiveType.Word32, regDx, regAx);
                m.Assign(dx_ax, m.Mem32(m.Word32(0x00123400)));
                m.Alias(ax, m.Slice(ax.DataType, dx_ax, 0));
                m.Alias(dx, m.Slice(ax.DataType, dx_ax, 16));
                m.AddUseToExitBlock(ax);
                m.AddUseToExitBlock(dx);
            },
                p =>
            {
                var flow = new ProcedureFlow(p);
                flow.BitsLiveOut.Add(seqDxAx, new BitRange(0, 32));
                return(flow);
            });
        }
Esempio n. 5
0
        public Identifier VisitSequenceStorage(SequenceStorage seq)
        {
            var dt = this.dt;
            var hd = (Identifier)seq.Head.Accept(this);
            var tl = (Identifier)seq.Tail.Accept(this);

            return(procCalling.Frame.EnsureSequence(hd.Storage, tl.Storage, dt));
        }
Esempio n. 6
0
        public Identifier VisitSequenceStorage(SequenceStorage seq)
        {
            var idSeq   = id;
            var newHead = seq.Head.Accept(this);
            var newTail = seq.Tail.Accept(this);

            return(frame.EnsureSequence(newHead.Storage, newTail.Storage, idSeq.DataType));
        }
Esempio n. 7
0
 public bool VisitSequenceStorage(SequenceStorage seq, bool defining)
 {
     foreach (var e in seq.Elements)
     {
         e.Accept(this, defining);
     }
     return(true);
 }
Esempio n. 8
0
        public Identifier VisitSequenceStorage(SequenceStorage seq)
        {
            var idSeq   = id;
            var newHead = (Identifier)VisitIdentifier(seq.Head);
            var newTail = (Identifier)VisitIdentifier(seq.Tail);

            return(frame.EnsureSequence(newHead, newTail, idSeq.DataType));
        }
Esempio n. 9
0
            public bool VisitSequenceStorage(SequenceStorage seq)
            {
                var f = seq.Head.Storage.Accept(this);

                if (!f)
                {
                    f = seq.Tail.Storage.Accept(this);
                }
                return(f);
            }
Esempio n. 10
0
        public Expression VisitSequenceStorage(SequenceStorage seq)
        {
            if (map.TryGetValue(seq, out var binding))
            {
                return(binding.Expression);
            }
            var exps = seq.Elements
                       .Select(stg => stg.Accept(this))
                       .ToArray();

            return(new MkSequence(seq.DataType, exps));
        }
Esempio n. 11
0
 public Storage VisitSequenceStorage(SequenceStorage seq)
 {
     seq.Head.Accept(this);
     seq.Tail.Accept(this);
     if (defining)
     {
         regDefs[seq] = value;
     }
     else
     {
         value = regDefs[seq];
     }
     return(seq);
 }
Esempio n. 12
0
        /// <summary>
        /// Inserts an alias statement.
        /// </summary>
        /// <param name="v">Variable that has been defined</param>
        /// <param name="vAlias">Other variable that is aliased by v</param>
        /// <param name="iAt"></param>
        // If a wide register is being defined by aliasing of a smaller
        // register, the expression needs to take into account the previous
        // value of the wide register. For instance, modifying cl aliases
        // cx = f(cl, cx)
        // thus:
        //	mov cl,xx
        //  mov cx,DPB(cx,cl,0,8)
        public Assignment CreateAliasInstruction(Identifier varFrom, Identifier varTo)         // Identifier v, Identifier vAlias)
        {
            if (!IsAlias(arch, varFrom, varTo))
            {
                throw new ApplicationException(string.Format("Unexpected alias pair {0} and {1}", varTo.Name, varFrom.Name));
            }

            Expression aliasExpr;

            int offsetTo   = varTo.Storage.OffsetOf(varFrom.Storage);
            int offsetFrom = varFrom.Storage.OffsetOf(varTo.Storage);

            int cbitsFrom = varFrom.DataType.BitSize;
            int cbitsTo   = varTo.DataType.BitSize;

            if (cbitsFrom < cbitsTo)
            {
                // We are replacing a part of a wider register with a narrower one.

                SequenceStorage seq = varTo.Storage as SequenceStorage;
                if (seq != null && (seq.Head == varFrom.Storage || seq.Tail == varFrom.Storage))
                {
                    aliasExpr = new MkSequence(
                        varTo.DataType,
                        proc.Frame.EnsureIdentifier(seq.Head),
                        proc.Frame.EnsureIdentifier(seq.Tail));
                }
                else
                {
                    aliasExpr = new DepositBits(varTo, varFrom, offsetTo);
                }
            }
            else if (cbitsFrom > cbitsTo)
            {
                if (offsetFrom == 0)
                {
                    aliasExpr = new Cast(varTo.DataType, varFrom);
                }
                else
                {
                    aliasExpr = new Slice(varTo.DataType, varFrom, offsetFrom);
                }
            }
            else
            {
                aliasExpr = varFrom;
            }
            return(new AliasAssignment(varTo, aliasExpr));
        }
Esempio n. 13
0
 public Storage VisitSequenceStorage(SequenceStorage seq)
 {
     seq.Head.Accept(this);
     seq.Tail.Accept(this);
     if (define)
     {
         defBitSize = (int)(seq.Head.BitSize + seq.Tail.BitSize);
         defOffset  = 0;
     }
     else
     {
         //$NOTimplemented: what happens in cases like es_bx = AAAABBBB
         // but only es is live out? AAAA but not BBBB should be live then.
     }
     return(null);
 }
Esempio n. 14
0
        public void FrSequenceAccess()
        {
            var             f      = new Frame(PrimitiveType.Word16);
            Identifier      ax     = f.EnsureRegister(Registers.ax);
            Identifier      dx     = f.EnsureRegister(Registers.dx);
            Identifier      dx_ax  = f.EnsureSequence(PrimitiveType.Word32, dx.Storage, ax.Storage);
            SequenceStorage vDx_ax = (SequenceStorage)dx_ax.Storage;

            using (FileUnitTester fut = new FileUnitTester("Core/FrSequenceAccess.txt"))
            {
                f.Write(fut.TextWriter);
                fut.TextWriter.WriteLine("Head({0}) = {1}", dx_ax.Name, vDx_ax.Elements[0].Name);
                fut.TextWriter.WriteLine("Tail({0}) = {1}", dx_ax.Name, vDx_ax.Elements[1].Name);

                fut.AssertFilesEqual();
            }
        }
Esempio n. 15
0
        public void TrashVariable(Storage id)
        {
            if (id == null)
            {
                return;
            }
            var reg = id as RegisterStorage;

            if (reg != null)
            {
                state.SetValue(reg, Constant.Invalid);
            }
            SequenceStorage seq = id as SequenceStorage;

            if (seq != null)
            {
                TrashVariable(seq.Head);
                TrashVariable(seq.Tail);
            }
        }
Esempio n. 16
0
        private void GenerateReturnValue(DataType dtRet, ICallingConventionEmitter ccr)
        {
            int size = dtRet.Size;

            if ((size & 1) != 0) // odd sized register occupies two regs
            {
                // Round size to even # of bytes.
                size = dtRet.Size + 1;
            }

            var iReg = 26 - size;

            if (dtRet.Size <= 8)
            {
                var reg = argRegs[iReg - 8];
                if (dtRet.Size == 1)
                {
                    ccr.RegReturn(reg);
                    return;
                }

                SequenceStorage seq = null;
                for (int r = iReg + 1, i = 1; i < dtRet.Size; ++i, ++r)
                {
                    var regNext = argRegs[r - 8];
                    if (seq != null)
                    {
                        seq = new SequenceStorage(regNext, seq, PrimitiveType.Word32);
                    }
                    else
                    {
                        seq = new SequenceStorage(regNext, reg, PrimitiveType.Word32);
                    }
                }
                ccr.SequenceReturn(seq);
            }
            else
            {
                throw new NotImplementedException("Large AVR8 return values not implemented yet.");
            }
        }
Esempio n. 17
0
        private void GenerateReturnValue(DataType dtRet, ICallingConventionEmitter ccr)
        {
            int size = dtRet.Size;

            if ((size & 1) != 0) // odd sized register occupies two regs
            {
                // Round size to even # of bytes.
                size = dtRet.Size + 1;
            }

            var iReg = 26 - size;

            if (dtRet.Size <= 8)
            {
                var reg = argRegs[iReg - 8];
                if (dtRet.Size == 1)
                {
                    ccr.RegReturn(reg);
                    return;
                }

                var retRegs = new List <RegisterStorage> {
                    reg
                };
                for (int r = iReg + 1, i = 1; i < dtRet.Size; ++i, ++r)
                {
                    var regNext = argRegs[r - 8];
                    retRegs.Insert(0, regNext);
                }
                var seq = new SequenceStorage(retRegs.ToArray());
                ccr.SequenceReturn(seq);
            }
            else
            {
                throw new NotImplementedException("Large AVR8 return values not implemented yet.");
            }
        }
Esempio n. 18
0
 public SerializedSequence(SequenceStorage seq)
 {
     Registers = seq.Elements
                 .Select(e => new Register_v1(e.Name))
                 .ToArray();
 }
Esempio n. 19
0
 public Storage VisitSequenceStorage(SequenceStorage seq)
 {
     ctx.RegisterState[seq] = value;
     return(seq);
 }
Esempio n. 20
0
 public SerializedSequence(SequenceStorage seq)
 {
     Registers    = new Register_v1[2];
     Registers[0] = new Register_v1(seq.Head.Name);
     Registers[1] = new Register_v1(seq.Tail.Name);
 }
Esempio n. 21
0
 public bool VisitSequenceStorage(SequenceStorage seq, bool defining)
 {
     seq.Head.Accept(this, defining);
     seq.Tail.Accept(this, defining);
     return(true);
 }
Esempio n. 22
0
 public Identifier VisitSequenceStorage(SequenceStorage seq)
 {
     return(frame.EnsureSequence(id.DataType, seq.Elements));
 }
Esempio n. 23
0
 public SequenceOperand(SequenceStorage seq) : base((PrimitiveType)seq.DataType)
 {
     this.Sequence = seq;
 }
Esempio n. 24
0
 public static Identifier Create(SequenceStorage seq)
 {
     return(new Identifier(seq.Name, seq.DataType, seq));
 }
Esempio n. 25
0
 public Storage VisitSequenceStorage(SequenceStorage seq)
 {
     return(null);
 }
Esempio n. 26
0
 public SerializedSequence(SequenceStorage seq)
 {
     Registers = new Register_v1[2];
     Registers[0] = new Register_v1(seq.Head.Name);
     Registers[1] = new Register_v1(seq.Tail.Name);
 }
Esempio n. 27
0
        public void Generate(ICallingConventionEmitter ccr, DataType dtRet, DataType dtThis, List <DataType> dtParams)
        {
            /*
             * To find the register where a function argument is passed, initialize the register number
             * Rn with R26 and follow this procedure:
             *
             * If the argument size is an odd number of bytes, round up the size to the next even number.
             * Subtract the rounded size from the register number Rn.
             *
             * If the new Rn is at least R8 and the size of the object is non-zero, then the low-byte of
             * the argument is passed in Rn. Subsequent bytes of the argument are passed in the subsequent
             * registers, i.e. in increasing register numbers.
             *
             * If the new register number Rn is smaller than R8 or the size of the argument is zero, the
             * argument will be passed in memory.
             *
             * If the current argument is passed in memory, stop the procedure: All subsequent arguments
             * will also be passed in memory.
             * If there are arguments left, goto 1. and proceed with the next argument.
             *
             * Return values with a size of 1 byte up to and including a size of 8 bytes will be returned
             * in registers. Return values whose size is outside that range will be returned in memory.
             * If a return value cannot be returned in registers, the caller will allocate stack space and
             * pass the address as implicit first pointer argument to the callee. The callee will put the
             * return value into the space provided by the caller.
             *
             * If the return value of a function is returned in registers, the same registers are used as
             * if the value was the first parameter of a non-varargs function. For example, an 8-bit value is returned in R24 and an 32-bit value is returned R22...R25.
             * Arguments of varargs functions are passed on the stack. This applies even to the named arguments.
             */
            ccr.LowLevelDetails(1, 2);

            if (dtRet != null || dtRet == VoidType.Instance)
            {
                GenerateReturnValue(dtRet, ccr);
            }

            int iReg = 26;

            foreach (var dtParam in dtParams)
            {
                int size = dtParam.Size;
                if ((size & 1) != 0) // odd sized register occupies two regs
                {
                    // Round size to even # of bytes.
                    size = dtParam.Size + 1;
                }
                iReg -= size;
                if (iReg >= 8)
                {
                    var reg = argRegs[iReg - 8];
                    if (dtParam.Size == 1)
                    {
                        ccr.RegParam(reg);
                        continue;
                    }

                    SequenceStorage seq = null;
                    for (int r = iReg + 1, i = 1; i < dtParam.Size; ++i, ++r)
                    {
                        var regNext = argRegs[r - 8];
                        if (seq != null)
                        {
                            seq = new SequenceStorage(regNext, seq, PrimitiveType.CreateWord(regNext.DataType.BitSize + seq.DataType.BitSize));
                        }
                        else
                        {
                            seq = new SequenceStorage(regNext, reg, PrimitiveType.CreateWord(regNext.DataType.BitSize + reg.DataType.BitSize));
                        }
                    }
                    ccr.SequenceParam(seq);
                }
                else
                {
                    ccr.StackParam(dtParam);
                }
            }
        }
Esempio n. 28
0
 public string VisitSequenceStorage(SequenceStorage seq)
 {
     return("seq");
 }