Beispiel #1
0
 private MemoryAccess RewriteMemoryOperand(MemoryOperand memop)
 {
     if (memop.Base != null)
     {
         Expression baseReg;
         if (memop.Base == Registers.pc)
         {
             baseReg = instr.Address + instr.Length;
         }
         else
         {
             baseReg = binder.EnsureRegister(memop.Base);
         }
         Expression ea = baseReg;
         if (memop.Index != null)
         {
             Expression idx = binder.EnsureRegister(memop.Index);
             if (idx.DataType.BitSize < ea.DataType.BitSize)
             {
                 idx = m.Cast(PrimitiveType.UInt16, idx);
             }
             ea = m.IAdd(baseReg, idx);
         }
         else if (memop.PreIncrement)
         {
             m.Assign(ea, m.IAddS(ea, memop.Offset.Value));
         }
         else if (memop.PostIncrement)
         {
             var tmp = binder.CreateTemporary(baseReg.DataType);
             m.Assign(tmp, ea);
             m.Assign(baseReg, m.IAddS(baseReg, memop.Offset.Value));
             ea = tmp;
         }
         else
         {
             ea = m.IAdd(baseReg, (ushort)memop.Offset.Value);
         }
         if (memop.Indirect)
         {
             ea = m.Mem(PrimitiveType.Ptr16, ea);
         }
         return(m.Mem(memop.Width, ea));
     }
     else
     {
         Debug.Assert(memop.Offset != null);
         return(m.Mem(memop.Width, Address.Ptr16((ushort)memop.Offset.Value)));
     }
 }
Beispiel #2
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();
             */
        }
Beispiel #3
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)
        {
            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.Cast(DataWidth, r);
                    }
                    else
                    {
                        r = m.Slice(DataWidth, r, 0);
                    }
                }
                return(r);

            case M68kImmediateOperand imm:
                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()));
                }

            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.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)));

            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.Cast(PrimitiveType.Word32, m.Cast(PrimitiveType.Int16, idx));
                    }
                    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);
        }
Beispiel #4
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);
        }
Beispiel #5
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.Cast(width, reg));
                }

            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)
                    {
                        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:
                return(addrOp.Address);
            }
            throw new NotImplementedException(op.GetType().Name);
        }
Beispiel #6
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);
        }