Esempio n. 1
0
        //$REFACTOR: this probably should live in X86FrameApplicationBuilder
        public override Expression CreateFpuStackAccess(IStorageBinder binder, int offset, DataType dataType)
        {
            Expression e = binder.EnsureRegister(Registers.Top);

            if (offset != 0)
            {
                BinaryOperator op;
                if (offset < 0)
                {
                    offset = -offset;
                    op     = Operator.ISub;
                }
                else
                {
                    op = Operator.IAdd;
                }
                e = new BinaryExpression(op, e.DataType, e, Constant.Create(e.DataType, offset));
            }
            return(new MemoryAccess(Registers.ST, e, dataType));
        }
Esempio n. 2
0
        private Expression RewriteOp(MachineOperand op)
        {
            switch (op)
            {
            case RegisterOperand rop:
                if (rop.Register.Number == 0)
                {
                    //$TODO: 32-bit!
                    return(Constant.Word64(0));
                }
                return(binder.EnsureRegister(rop.Register));

            case ImmediateOperand immop:
                return(immop.Value);

            case AddressOperand addrop:
                return(addrop.Address);
            }
            throw new NotImplementedException($"Rewriting RiscV addressing mode {op.GetType().Name} is not implemented yet.");
        }
Esempio n. 3
0
        private Expression RewriteOp(MachineOperand op)
        {
            var rOp = op as RegisterOperand;

            if (rOp != null)
            {
                return(binder.EnsureRegister(rOp.Register));
            }
            var aOp = op as AddressOperand;

            if (aOp != null)
            {
                return(aOp.Address);
            }
            var iOp = op as ImmediateOperand;

            if (iOp != null)
            {
                return(iOp.Value);
            }
            throw new NotImplementedException(op.GetType().FullName);
        }
Esempio n. 4
0
        private Expression EffectiveAddress(MemoryOperand mem)
        {
            if (mem.Base == null || mem.Base.Number == 0)
            {
                // Must be abs address.
                return(Address.Create(arch.PointerType, (uint)mem.Offset));
            }
            Expression ea = binder.EnsureRegister(mem.Base);

            if (mem.Index != null && mem.Index.Number > 0)
            {
                var idx = binder.EnsureRegister(mem.Index);
                ea = m.IAdd(ea, idx);
            }
            if (mem.Offset != 0)
            {
                var off = Constant.Int(mem.Base.DataType, mem.Offset);
                ea = m.IAdd(ea, off);
            }
            return(ea);
        }
Esempio n. 5
0
        private Expression RewriteSrc(MachineOperand op)
        {
            switch (op)
            {
            case RegisterOperand reg:
                return(binder.EnsureRegister(reg.Register));

            case AddressOperand addr:
                return(addr.Address);

            case ImmediateOperand imm:
                return(imm.Value);

            case MemoryOperand mem:
                Expression ea;
                if (mem.Base != null)
                {
                    ea = binder.EnsureRegister(mem.Base);
                    if (mem.Index != null)
                    {
                        var idx = binder.EnsureRegister(mem.Index);
                        ea = m.IAdd(
                            ea,
                            m.Convert(idx, idx.DataType, PrimitiveType.Int16));
                    }
                    else if (mem.Offset != null)
                    {
                        ea = m.IAdd(
                            ea,
                            m.Int16((sbyte)mem.Offset.ToByte()));
                    }
                }
                else
                {
                    ea = arch.MakeAddressFromConstant(mem.Offset, false);
                }
                var tmp = binder.CreateTemporary(mem.Width);
                m.Assign(tmp, m.Mem(mem.Width, ea));
                return(tmp);
            }
            throw new NotImplementedException(op.GetType().Name);
        }
Esempio n. 6
0
        private void RewriteJz(Func <Expression, Expression> cmp)
        {
            iclass = InstrClass.ConditionalTransfer;
            var src  = binder.EnsureRegister(Registers.A);
            var addr = ((AddressOperand)instr.Operands[0]).Address;

            m.Branch(cmp(src), addr, InstrClass.ConditionalTransfer);
        }
Esempio n. 7
0
        private Expression RewriteOp(MachineOperand op)
        {
            switch (op)
            {
            case RegisterOperand rop:
                return(binder.EnsureRegister(rop.Register));

            case ImmediateOperand immop:
                return(immop.Value);

            case MemoryOperand memop:
                return(RewriteMemoryOperand(memop));
            }
            throw new NotImplementedException();
        }
Esempio n. 8
0
        }                                                // the data width of the current instruction being rewritten.

        /// <summary>
        /// Rewrite operands being used as sources.
        /// </summary>
        /// <param name="operand"></param>
        /// <param name="addrInstr">Address of the current instruction</param>
        public Expression RewriteSrc(MachineOperand operand, Address addrInstr, bool addressAsAddress = false)
        {
            Expression ea;
            Expression r;

            switch (operand)
            {
            case RegisterOperand reg:
                r = binder.EnsureRegister(reg.Register);
                if (DataWidth != null && DataWidth.Size != reg.Width.Size)
                {
                    if (DataWidth.Domain == Domain.Real)
                    {
                        r = m.Convert(r, r.DataType, DataWidth);
                    }
                    else
                    {
                        r = m.Slice(DataWidth, r, 0);
                    }
                }
                return(r);

            case M68kImmediateOperand imm:
                if (imm.Width.IsReal)
                {
                    return(imm.Constant.CloneExpression());
                }
                if (DataWidth != null && DataWidth.BitSize > imm.Width.BitSize)
                {
                    return(Constant.Create(DataWidth, imm.Constant.ToInt64()));
                }
                else
                {
                    return(Constant.Create(imm.Width, imm.Constant.ToUInt32()));
                }

            case MemoryOperand mem:
                return(RewriteMemoryAccess(mem, DataWidth, addrInstr));

            case M68kAddressOperand addr:
                if (addressAsAddress)
                {
                    return(addr.Address);
                }
                else
                {
                    return(m.Mem(DataWidth, addr.Address));
                }

            case PredecrementMemoryOperand pre:
                ea = binder.EnsureRegister(pre.Register);
                m.Assign(ea, m.ISubS(ea, DataWidth.Size));
                return(m.Mem(DataWidth, ea));

            case PostIncrementMemoryOperand post:
                r = binder.EnsureRegister(post.Register);
                var tmp = binder.CreateTemporary(DataWidth);
                m.Assign(tmp, m.Mem(DataWidth, r));
                m.Assign(r, m.IAddS(r, DataWidth.Size));
                return(tmp);

            case IndirectIndexedOperand indidx:
                ea = RewriteIndirectBaseRegister(indidx, addrInstr);
                Expression ix = binder.EnsureRegister(indidx.XRegister);
                if (indidx.XWidth.Size != 4)
                {
                    ix = m.Slice(PrimitiveType.Int16, ix, 0);
                    ix = m.Convert(ix, PrimitiveType.Int16, PrimitiveType.Int32);
                }
                if (indidx.Scale > 1)
                {
                    ix = m.IMul(ix, Constant.Int32(indidx.Scale));
                }
                return(m.Mem(DataWidth, m.IAdd(ea, ix)));

            case IndexedOperand indop:
                ea = Combine(indop.BaseDisplacement, indop.Base, addrInstr);
                if (indop.postindex)
                {
                    ea = m.Mem32(ea);
                }
                if (indop.Index != null)
                {
                    var idx = Combine(null, indop.Index, addrInstr);
                    if (indop.index_reg_width !.BitSize != 32)
                    {
                        idx = m.Convert(m.Slice(PrimitiveType.Int16, idx, 0), PrimitiveType.Int16, PrimitiveType.Int32);
                    }
                    if (indop.IndexScale > 1)
                    {
                        idx = m.IMul(idx, indop.IndexScale);
                    }
                    ea = Combine(ea, idx);
                }
                if (indop.preindex)
                {
                    ea = m.Mem32(ea);
                }
                ea = Combine(ea, indop.OuterDisplacement);
                return(m.Mem(DataWidth, ea));
            }
            throw new NotImplementedException("Unimplemented RewriteSrc for operand type " + operand.GetType().Name);
        }
Esempio n. 9
0
 public void AddRegisterArgument(RegisterStorage reg)
 {
     AddInParam(binder.EnsureRegister(reg));
 }
Esempio n. 10
0
        protected Identifier Fsr2;    // cached FSR2 register identifier

        protected PIC18RewriterBase(PICArchitecture arch, PICDisassemblerBase disasm, PICProcessorState state, IStorageBinder binder, IRewriterHost host)
            : base(arch, disasm, state, binder, host)
        {
            Fsr2 = binder.EnsureRegister(PIC18Registers.FSR2);
        }
Esempio n. 11
0
        private Expression RewriteJmpSrc(MachineOperand op)
        {
            var memOp = op as MemoryOperand;

            if (memOp == null)
            {
                // PDP-11 always has a memory reference
                // for the destination of a transfer instruction.
                return(null);
            }
            var r = memOp.Register != null
                ? binder.EnsureRegister(memOp.Register)
                : null;

            var tmp = binder.CreateTemporary(op.Width);

            switch (memOp.Mode)
            {
            default:
                throw new AddressCorrelatedException(
                          dasm.Current.Address,
                          "Not implemented: addressing mode {0}.",
                          memOp.Mode);

            case AddressMode.RegDef:
                return(r);

            case AddressMode.Absolute:
                return(Address.Ptr16(memOp.EffectiveAddress));

            case AddressMode.AutoIncr:
                m.Assign(tmp, m.Mem(PrimitiveType.Ptr16, r));
                m.Assign(r, m.IAdd(r, memOp.Width.Size));
                break;

            case AddressMode.AutoIncrDef:
                m.Assign(tmp, m.Mem(op.Width, r));
                m.Assign(r, m.IAdd(r, memOp.Width.Size));
                break;

            case AddressMode.AutoDecr:
                m.Assign(r, m.ISub(r, memOp.Width.Size));
                return(m.Mem(op.Width, r));

            case AddressMode.AutoDecrDef:
                m.Assign(r, m.ISub(r, memOp.Width.Size));
                m.Assign(tmp, m.Mem(op.Width, m.Mem(PrimitiveType.Ptr16, r)));
                return(tmp);

            case AddressMode.Indexed:
                if (memOp.Register == Registers.pc)
                {
                    var offset   = (short)memOp.EffectiveAddress;
                    var addrBase = (long)instr.Address.ToLinear();
                    var addr     = Address.Ptr16((ushort)(instr.Length + addrBase + offset));
                    return(addr);
                }
                else
                {
                    return(m.Mem(
                               this.dasm.Current.DataWidth,
                               m.IAdd(r, Constant.Word16(memOp.EffectiveAddress))));
                }

            case AddressMode.IndexedDef:
                if (memOp.Register == Registers.pc)
                {
                    var offset   = (short)memOp.EffectiveAddress;
                    var addrBase = (long)instr.Address.ToLinear() + instr.Length;
                    var addr     = Constant.Word16((ushort)(addrBase + offset));
                    return(m.Mem(
                               PrimitiveType.Word16,
                               addr));
                }
                else
                {
                    return(m.Mem(
                               PrimitiveType.Ptr16,
                               m.IAdd(r, Constant.Word16(memOp.EffectiveAddress))));
                }
            }
            return(tmp);

            /*
             *  var immOp = op as ImmediateOperand;
             *  if (immOp != null)
             *  {
             *      return immOp.Value;
             *  }
             *  var addrOp = op as AddressOperand;
             *  if (addrOp != null)
             *  {
             *      return addrOp.Address;
             *  }
             *  throw new NotImplementedException();
             */
        }
Esempio n. 12
0
 public Identifier AluRegister(RegisterOperand reg)
 {
     return(binder.EnsureRegister(reg.Register));
 }
Esempio n. 13
0
        public override Expression CreateStackAccess(IStorageBinder binder, int cbOffset, DataType dataType)
        {
            var sp = binder.EnsureRegister(this.StackRegister);

            return(MemoryAccess.Create(sp, cbOffset, dataType));
        }
Esempio n. 14
0
        private Expression RewriteSrcOp(int iOp, PrimitiveType width)
        {
            var op    = dasm.Current.Operands[iOp];
            var regOp = op as RegisterOperand;

            if (regOp != null)
            {
                var reg = binder.EnsureRegister(regOp.Register);
                if (reg == null)
                {
                    return(null);
                }
                if (width.Size == 4)
                {
                    return(reg);
                }
                else if (width.Size == 8)
                {
                    var rHi = arch.GetRegister(1 + (int)reg.Storage.Domain);
                    if (rHi == null)
                    {
                        return(null);
                    }
                    var regHi = binder.EnsureRegister(rHi);
                    return(binder.EnsureSequence(regHi.Storage, reg.Storage, width));
                }
                else if (width.Size == 16)
                {
                    var regHi1 = binder.EnsureRegister(arch.GetRegister(1 + (int)reg.Storage.Domain));
                    var regHi2 = binder.EnsureRegister(arch.GetRegister(2 + (int)reg.Storage.Domain));
                    var regHi3 = binder.EnsureRegister(arch.GetRegister(3 + (int)reg.Storage.Domain));

                    var regLo = binder.EnsureSequence(regHi1.Storage, reg.Storage, PrimitiveType.Word64);
                    var regHi = binder.EnsureSequence(regHi3.Storage, regHi2.Storage, PrimitiveType.Word64);
                    return(binder.EnsureSequence(regHi.Storage, regLo.Storage, width));
                }
                else
                {
                    return(m.Cast(width, reg));
                }
            }
            var immOp = op as ImmediateOperand;

            if (immOp != null)
            {
                return(immOp.Value);
            }
            var memOp = op as MemoryOperand;

            if (memOp != null)
            {
                Expression ea;
                if (memOp.Base != null)
                {
                    var reg = binder.EnsureRegister(memOp.Base);
                    if (memOp.AutoDecrement)
                    {
                        m.Assign(reg, m.ISub(reg, width.Size));
                    }
                    else if (memOp.AutoIncrement)
                    {
                        var tmp = binder.CreateTemporary(reg.DataType);
                        m.Assign(tmp, reg);
                        reg = tmp;
                    }
                    ea = reg;
                    if (memOp.Offset != null)
                    {
                        ea = m.IAdd(ea, memOp.Offset);
                    }
                    if (memOp.Index != null)
                    {
                        Expression idx = binder.EnsureRegister(memOp.Index);
                        if (width.Size != 1)
                        {
                            idx = m.IMul(idx, Constant.Int32(width.Size));
                        }
                        ea = m.IAdd(ea, idx);
                    }
                    Expression load;
                    if (memOp.Deferred)
                    {
                        load = m.Mem(width, m.Mem32(ea));
                    }
                    else
                    {
                        load = m.Mem(width, ea);
                    }
                    if (memOp.AutoIncrement)
                    {
                        if (memOp.AutoIncrement)
                        {
                            reg = binder.EnsureRegister(memOp.Base);
                            int inc = (memOp.Deferred) ? 4 : width.Size;
                            m.Assign(reg, m.IAdd(reg, inc));
                        }
                    }
                    return(load);
                }
                else
                {
                }
            }
            var addrOp = op as AddressOperand;

            if (addrOp != null)
            {
                return(addrOp.Address);
            }
            throw new NotImplementedException(op.GetType().Name);
        }
Esempio n. 15
0
        private Expression Operand(MachineOperand op)
        {
            switch (op)
            {
            case RegisterOperand rop:
                return(binder.EnsureRegister(rop.Register));

            case ImmediateOperand imm:
                return(imm.Value);

            case MemoryOperand mem:
                Expression ea;
                if (mem.Address != null)
                {
                    if (mem.Register != null)
                    {
                        ea = m.IAdd(
                            mem.Address,
                            m.Cast(PrimitiveType.UInt16, binder.EnsureRegister(mem.Register)));
                    }
                    else
                    {
                        ea = mem.Address;
                    }
                }
                else
                {
                    ea = RegisterPair(mem.Register);
                }
                return(m.Mem(mem.Width, ea));

            case AddressOperand addr:
                return(addr.Address);

            default:
                throw new NotImplementedException(op.GetType().Name);
            }
        }
Esempio n. 16
0
        private void Copy(RegisterStorage regDst, RegisterStorage regSrc)
        {
            var dst = binder.EnsureRegister(regDst);
            var src = binder.EnsureRegister(regSrc);

            m.Assign(dst, src);
            m.Assign(
                binder.EnsureFlagGroup(
                    Registers.p,
                    (uint)(FlagM.NF | FlagM.ZF),
                    "NZ",
                    PrimitiveType.Byte),
                m.Cond(dst));
        }
Esempio n. 17
0
        private void RewriteBlockInstruction(Func <Expression, Expression, Expression> incdec, bool repeat)
        {
            var bc = binder.EnsureRegister(Registers.bc);
            var de = binder.EnsureRegister(Registers.de);
            var hl = binder.EnsureRegister(Registers.hl);
            var V  = FlagGroup(FlagM.PF);

            m.Assign(m.Mem8(de), m.Mem8(hl));
            m.Assign(hl, incdec(hl, Constant.Int16(1)));
            m.Assign(de, incdec(de, Constant.Int16(1)));
            m.Assign(bc, m.ISub(bc, 1));
            if (repeat)
            {
                m.BranchInMiddleOfInstruction(m.Ne0(bc), dasm.Current.Address, InstrClass.Transfer);
            }
            m.Assign(V, m.Const(PrimitiveType.Bool, 0));
        }
Esempio n. 18
0
        }                                                // the data width of the current instruction being rewritten.

        /// <summary>
        /// Rewrite operands being used as sources.
        /// </summary>
        /// <param name="operand"></param>
        /// <param name="addrInstr">Address of the current instruction</param>
        /// <returns></returns>
        public Expression RewriteSrc(MachineOperand operand, Address addrInstr, bool addressAsAddress = false)
        {
            var reg = operand as RegisterOperand;

            if (reg != null)
            {
                Expression r = binder.EnsureRegister(reg.Register);
                if (DataWidth != null && DataWidth.Size != reg.Width.Size)
                {
                    r = m.Cast(DataWidth, r);
                }
                return(r);
            }
            var imm = operand as M68kImmediateOperand;

            if (imm != null)
            {
                if (imm.Width.Domain == Domain.Real)
                {
                    return(imm.Constant.CloneExpression());
                }
                if (DataWidth != null && DataWidth.BitSize > imm.Width.BitSize)
                {
                    return(Constant.Create(DataWidth, imm.Constant.ToInt64()));
                }
                else
                {
                    return(Constant.Create(imm.Width, imm.Constant.ToUInt32()));
                }
            }
            var mem = operand as MemoryOperand;

            if (mem != null)
            {
                return(RewriteMemoryAccess(mem, DataWidth, addrInstr));
            }
            var addr = operand as M68kAddressOperand;

            if (addr != null)
            {
                if (addressAsAddress)
                {
                    return(addr.Address);
                }
                else
                {
                    return(m.Mem(DataWidth, addr.Address));
                }
            }
            var pre = operand as PredecrementMemoryOperand;

            if (pre != null)
            {
                var ea = binder.EnsureRegister(pre.Register);
                m.Assign(ea, m.ISub(ea, m.Int32(DataWidth.Size)));
                return(m.Mem(DataWidth, ea));
            }
            var post = operand as PostIncrementMemoryOperand;

            if (post != null)
            {
                var r   = binder.EnsureRegister(post.Register);
                var tmp = binder.CreateTemporary(DataWidth);
                m.Assign(tmp, m.Mem(DataWidth, r));
                m.Assign(r, m.IAdd(r, m.Int32(DataWidth.Size)));
                return(tmp);
            }
            var indidx = operand as IndirectIndexedOperand;

            if (indidx != null)
            {
                Expression ea = RewriteIndirectBaseRegister(indidx, addrInstr);
                Expression ix = binder.EnsureRegister(indidx.XRegister);
                if (indidx.XWidth.Size != 4)
                {
                    ix = m.Cast(PrimitiveType.Int32, m.Cast(PrimitiveType.Int16, ix));
                }
                if (indidx.Scale > 1)
                {
                    ix = m.IMul(ix, Constant.Int32(indidx.Scale));
                }
                return(m.Mem(DataWidth, m.IAdd(ea, ix)));
            }
            var indop = operand as IndexedOperand;

            if (indop != null)
            {
                Expression ea = Combine(indop.Base, indop.base_reg);
                if (indop.postindex)
                {
                    ea = m.Mem32(ea);
                }
                if (indop.index_reg != null)
                {
                    var idx = Combine(null, indop.index_reg);
                    if (indop.index_reg_width.BitSize != 32)
                    {
                        idx = m.Cast(PrimitiveType.Word32, m.Cast(PrimitiveType.Int16, idx));
                    }
                    if (indop.index_scale > 1)
                    {
                        idx = m.IMul(idx, indop.index_scale);
                    }
                    ea = Combine(ea, idx);
                }
                if (indop.preindex)
                {
                    ea = m.Mem32(ea);
                }
                ea = Combine(ea, indop.outer);
                return(m.Mem(DataWidth, ea));
            }
            throw new NotImplementedException("Unimplemented RewriteSrc for operand type " + operand.GetType().Name);
        }
Esempio n. 19
0
        private void Push(RegisterStorage stackRegister, RegisterStorage reg)
        {
            var sp = binder.EnsureRegister(stackRegister);

            m.Assign(sp, m.ISubS(sp, reg.DataType.Size));
            m.Assign(m.Mem(reg.DataType, sp), binder.EnsureRegister(reg));
        }
Esempio n. 20
0
        private Expression?OperandSrc(MachineOperand op)
        {
            switch (op)
            {
            case RegisterOperand rop: return(binder.EnsureRegister(rop.Register));

            case ImmediateOperand imm: return(imm.Value);

            case AddressOperand addr: return(addr.Address);

            case ApplicationOperand app: return(RewriteApplication(app));

            case MemoryOperand mem: var src = RewriteMemoryOperand(mem); MaybeEmitIncrement(mem); return(src);

            case RegisterPairOperand pair: return(binder.EnsureSequence(PrimitiveType.Word64, pair.HighRegister, pair.LowRegister));

            case DecoratorOperand dec: return(RewriteDecorator(dec));
            }
            throw new NotImplementedException($"Hexagon rewriter for {op.GetType().Name} not implemented yet.");
        }
Esempio n. 21
0
        /// <summary>
        /// Make a function signature based on the procedure flow <paramref name="flow"/>.
        /// </summary>
        /// <returns>A valid function signature.</returns>
        public FunctionType MakeSignature(SsaState ssa, IStorageBinder frame, ProcedureFlow flow)
        {
            var allLiveOut   = flow.BitsLiveOut;
            var sb           = new SignatureBuilder(frame, platform.Architecture);
            var implicitRegs = platform.CreateImplicitArgumentRegisters();

            var liveOutFlagGroups = flow.grfLiveOut.Select(de => platform.Architecture.GetFlagGroup(de.Key, de.Value) !);

            AddModifiedFlags(frame, liveOutFlagGroups, sb);

            var mayUseSeqs = flow.BitsUsed.Keys.OfType <SequenceStorage>().ToHashSet();
            var seqRegs    = mayUseSeqs.SelectMany(s => s.Elements).Distinct().ToHashSet();

            //$BUG: should be sorted by ABI register order.
            foreach (var seq in mayUseSeqs.OrderBy(r => r.Name))
            {
                sb.AddSequenceArgument(seq);
            }
            var mayUseRegs = flow.BitsUsed
                             .Select(de => (Key: de.Key as RegisterStorage, de.Value))
                             .Where(b =>
            {
                return(b.Key is RegisterStorage reg && !implicitRegs.Contains(reg));
            })
                             .Select(MakeRegisterParameter)
                             .ToDictionary(de => de.Item1, de => de.Item2);

            //$BUG: should be sorted by ABI register order. Need a new method
            // IPlatform.CreateAbiRegisterCollator().
            foreach (var reg in mayUseRegs.OrderBy(r => r.Key.Number))
            {
                if (!IsSubRegisterOfRegisters(reg.Key, mayUseRegs) &&
                    !seqRegs.Contains(reg.Key))
                {
                    sb.AddRegisterArgument(reg.Key);
                }
            }

            foreach (var id in GetSortedStackArguments((Frame)frame, flow.BitsUsed))
            {
                sb.AddInParam(id.Item2);
            }

            foreach (var oFpu in flow.BitsUsed
                     .Where(f => f.Key is FpuStackStorage)
                     .OrderBy(r => ((FpuStackStorage)r.Key).FpuStackOffset))
            {
                var fpu = (FpuStackStorage)oFpu.Key;
                var id  = frame.EnsureFpuStackVariable(fpu.FpuStackOffset, fpu.DataType);
                sb.AddFpuStackArgument(fpu.FpuStackOffset, id);
            }

            var liveOut = allLiveOut
                          .Select(de => (Key: de.Key as RegisterStorage, de.Value))
                          .Where(de =>
            {
                return(de.Key != null &&
                       !implicitRegs.Contains(de.Key));
            })
                          .Select(MakeRegisterParameter)
                          .ToDictionary(de => de.Item1, de => de.Item2);

            // Sort the names in a stable way to avoid regression tests failing.
            foreach (var r in liveOut.OrderBy(r => r.Key.Number).ThenBy(r => r.Key.BitAddress))
            {
                if (!IsSubRegisterOfRegisters(r.Key, liveOut))
                {
                    var regOut = sb.AddOutParam(frame.EnsureRegister(r.Key));
                    if (regOut.Storage is OutArgumentStorage &&
                        !ssa.Identifiers.TryGetValue(regOut, out var sidOut))
                    {
                        // Ensure there are SSA identifiers for 'out' registers.
                        ssa.Identifiers.Add(regOut, null, null, false);
                    }
                }
            }

            foreach (var fpu in allLiveOut.Keys.OfType <FpuStackStorage>().OrderBy(r => r.FpuStackOffset))
            {
                sb.AddOutParam(frame.EnsureFpuStackVariable(fpu.FpuStackOffset, fpu.DataType));
            }

            var sig = sb.BuildSignature();

            return(sig);
        }
Esempio n. 22
0
        private Identifier Reg(int iOp)
        {
            var op = instrCur.Operands[iOp];
            var id = binder.EnsureRegister(((RegisterOperand)op).Register);

            return(id);
        }
Esempio n. 23
0
 public Expression VisitRegisterStorage(RegisterStorage reg)
 {
     return(binder.EnsureRegister(reg));
 }
Esempio n. 24
0
        private Expression RewriteOp(MachineOperand op, PrimitiveType?dt = null)
        {
            dt ??= op.Width ?? instr.dataWidth !;
            switch (op)
            {
            case RegisterOperand rop:
                return(binder.EnsureRegister(rop.Register));

            case MemoryOperand mop:
                Expression ea;
                if (mop.Base != null)
                {
                    ea = binder.EnsureRegister(mop.Base);
                    if (mop.PostIncrement)
                    {
                        var tmp = binder.CreateTemporary(dt);
                        m.Assign(tmp, m.Mem(op.Width !, ea));
                        m.Assign(ea, m.IAdd(ea, m.Int16((short)dt.Size)));
                        return(tmp);
                    }
                    else if (mop.Base == Registers.pc)
                    {
                        ea = instr.Address + mop.Offset;
                        var tmp = binder.CreateTemporary(dt);
                        m.Assign(tmp, m.Mem(dt, ea));
                        return(tmp);
                    }
                    else if (mop.Offset != 0)
                    {
                        var tmp = binder.CreateTemporary(dt);
                        m.Assign(tmp, m.Mem(dt, m.IAdd(ea, m.Int16(mop.Offset))));
                        return(tmp);
                    }
                    else
                    {
                        var tmp = binder.CreateTemporary(dt);
                        m.Assign(tmp, m.Mem(dt, ea));
                        return(tmp);
                    }
                }
                else
                {
                    var tmp = binder.CreateTemporary(dt);
                    ea = Address.Ptr16((ushort)mop.Offset);
                    m.Assign(tmp, m.Mem(dt, ea));
                    return(tmp);
                }

            case ImmediateOperand iop:
                return(iop.Value);

            case AddressOperand aop:
                return(aop.Address);
            }
            throw new NotImplementedException(op.ToString());
        }
Esempio n. 25
0
        private Expression SrcOp(MachineOperand op, Func <int, int> immediateFn = null)
        {
            var regOp = op as RegisterOperand;

            if (regOp != null)
            {
                var id = binder.EnsureRegister(regOp.Register);
                return(id);
            }
            var immOp = op as ImmediateOperand;

            if (immOp != null)
            {
                return(Constant.Word32(immediateFn(immOp.Value.ToInt32())));
            }
            var addrOp = op as AddressOperand;

            if (addrOp != null)
            {
                return(addrOp.Address);
            }
            var mem = op as MemoryOperand;

            if (mem != null)
            {
                Identifier reg;
                switch (mem.mode)
                {
                default:
                    throw new NotImplementedException(mem.mode.ToString());

                case AddressingMode.Indirect:
                    return(m.Mem(mem.Width, binder.EnsureRegister(mem.reg)));

                case AddressingMode.IndirectPreDecr:
                    reg = binder.EnsureRegister(mem.reg);
                    m.Assign(reg, m.ISubS(reg, mem.Width.Size));
                    return(m.Mem(mem.Width, reg));

                case AddressingMode.IndirectPostIncr:
                    var t = binder.CreateTemporary(mem.Width);
                    reg = binder.EnsureRegister(mem.reg);
                    m.Assign(t, m.Mem(mem.Width, reg));
                    m.Assign(reg, m.IAddS(reg, t.DataType.Size));
                    return(t);

                case AddressingMode.IndirectDisplacement:
                    reg = binder.EnsureRegister(mem.reg);
                    return(m.Mem(
                               mem.Width,
                               m.IAddS(reg, mem.disp)));

                case AddressingMode.IndexedIndirect:
                    return(m.Mem(mem.Width, m.IAdd(
                                     binder.EnsureRegister(Registers.r0),
                                     binder.EnsureRegister(mem.reg))));

                case AddressingMode.PcRelativeDisplacement:
                    var addr = instr.Address.ToUInt32();
                    if (mem.Width.Size == 4)
                    {
                        addr &= ~3u;
                    }
                    addr += (uint)(mem.disp + 4);
                    return(m.Mem(mem.Width, Address.Ptr32(addr)));
                }
            }
            throw new NotImplementedException(op.GetType().Name);
        }
Esempio n. 26
0
        public override Expression CreateStackAccess(IStorageBinder binder, int offset, DataType dataType)
        {
            var rsp = binder.EnsureRegister(Registers.rsp);

            return(MemoryAccess.Create(rsp, offset, dataType));
        }
Esempio n. 27
0
        private Expression RewriteSrcOp(int iOp, PrimitiveType width)
        {
            var op = this.instr.Operands[iOp];

            switch (op)
            {
            case RegisterOperand regOp:
                var reg = binder.EnsureRegister(regOp.Register);
                if (reg == null)
                {
                    return(null);
                }
                if (width.Size == 4)
                {
                    return(reg);
                }
                else if (width.Size == 8)
                {
                    var rHi = arch.GetRegister(1 + (int)reg.Storage.Domain);
                    if (rHi == null)
                    {
                        return(null);
                    }
                    var regHi = binder.EnsureRegister(rHi);
                    return(binder.EnsureSequence(width, regHi.Storage, reg.Storage));
                }
                else if (width.Size == 16)
                {
                    var regHi1 = binder.EnsureRegister(arch.GetRegister(1 + (int)reg.Storage.Domain));
                    var regHi2 = binder.EnsureRegister(arch.GetRegister(2 + (int)reg.Storage.Domain));
                    var regHi3 = binder.EnsureRegister(arch.GetRegister(3 + (int)reg.Storage.Domain));

                    var regLo = binder.EnsureSequence(PrimitiveType.Word64, regHi1.Storage, reg.Storage);
                    var regHi = binder.EnsureSequence(PrimitiveType.Word64, regHi3.Storage, regHi2.Storage);
                    return(binder.EnsureSequence(width, regHi.Storage, regLo.Storage));
                }
                else
                {
                    return(m.Slice(width, reg, 0));
                }

            case ImmediateOperand immOp:
                return(immOp.Value);

            case MemoryOperand memOp:
                Expression ea;
                if (memOp.Base != null)
                {
                    reg = binder.EnsureRegister(memOp.Base);
                    if (memOp.AutoDecrement)
                    {
                        m.Assign(reg, m.ISub(reg, width.Size));
                    }
                    else if (memOp.AutoIncrement)
                    {
                        var tmp = binder.CreateTemporary(reg.DataType);
                        m.Assign(tmp, reg);
                        reg = tmp;
                    }
                    ea = reg;
                    if (memOp.Offset != null)
                    {
                        if (memOp.Offset.DataType.BitSize < ea.DataType.BitSize)
                        {
                            ea = m.IAddS(ea, memOp.Offset.ToInt32());
                        }
                        else
                        {
                            ea = m.IAdd(ea, memOp.Offset);
                        }
                    }
                    if (memOp.Index != null)
                    {
                        Expression idx = binder.EnsureRegister(memOp.Index);
                        if (width.Size != 1)
                        {
                            idx = m.IMul(idx, Constant.Int32(width.Size));
                        }
                        ea = m.IAdd(ea, idx);
                    }
                    Expression load;
                    if (memOp.Deferred)
                    {
                        load = m.Mem(width, m.Mem32(ea));
                    }
                    else
                    {
                        load = m.Mem(width, ea);
                    }
                    if (memOp.AutoIncrement)
                    {
                        reg = binder.EnsureRegister(memOp.Base);
                        int inc = (memOp.Deferred) ? 4 : width.Size;
                        m.Assign(reg, m.IAdd(reg, inc));
                    }
                    return(load);
                }
                else
                {
                    ea = arch.MakeAddressFromConstant(memOp.Offset, false);
                    Expression load;
                    if (memOp.Deferred)
                    {
                        load = m.Mem(width, m.Mem32(ea));
                    }
                    else
                    {
                        load = m.Mem(width, ea);
                    }
                    return(load);
                }

            case AddressOperand addrOp:
                //$BUG: enabling the commented code causes huge regressions in the
                // unzip subject.

                /*if (addrOp.Width.BitSize > width.BitSize)
                 * {
                 *  var c = addrOp.Address.ToUInt32();
                 *  return Constant.Create(width, c);
                 * }
                 * else*/
            {
                return(addrOp.Address);
            }
            }
            throw new NotImplementedException(op.GetType().Name);
        }
Esempio n. 28
0
 private void RewriteJxx(RegisterStorage reg, Func <Expression, BinaryExpression> test)
 {
     m.Branch(test(binder.EnsureRegister(reg)), (Address)Op(0));
 }
Esempio n. 29
0
 public Identifier Register(int iReg)
 {
     return(binder.EnsureRegister(arch.GetRegister(iReg)));
 }
Esempio n. 30
0
        private void Pull(RegisterStorage stackptr, RegisterStorage reg)
        {
            var sp = binder.EnsureRegister(stackptr);
            var r  = binder.EnsureRegister(reg);

            if (reg == Registers.PCR)
            {
                m.Return(2, 0);
            }
            else
            {
                m.Assign(r, m.Mem(r.DataType, sp));
                m.Assign(sp, m.IAddS(sp, r.DataType.Size));
            }
        }