示例#1
0
        private Expression RewriteSrc(MachineOperand op)
        {
            var memOp = op as MemoryOperand;

            if (memOp != null)
            {
                var r   = frame.EnsureRegister(memOp.Register);
                var tmp = frame.CreateTemporary(op.Width);
                switch (memOp.Mode)
                {
                default:
                    throw new NotImplementedException(string.Format("Not implemented: addressing mode {0}.", memOp.Mode));

                case AddressMode.RegDef:
                    return(emitter.Load(this.instrs.Current.DataWidth, r));

                case AddressMode.AutoIncr:
                    emitter.Assign(tmp, emitter.Load(op.Width, r));
                    emitter.Assign(r, emitter.IAdd(r, memOp.Width.Size));
                    break;
                }
                return(tmp);
            }
            var regOp = op as RegisterOperand;

            if (regOp != null)
            {
                return(frame.EnsureRegister(regOp.Register));
            }
            throw new NotImplementedException();
        }
示例#2
0
        private Expression RewriteSrc(MachineOperand op)
        {
            var reg = op as RegisterOperand;

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

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

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

            if (mem != null)
            {
                Expression ea  = RewriteSrcEa(mem);
                var        tmp = binder.CreateTemporary(mem.Width);
                m.Assign(tmp, m.Load(mem.Width, ea));
                return(tmp);
            }

            throw new NotImplementedException(op.GetType().Name);
        }
示例#3
0
        private Expression Operand(ArmInstructionOperand op)
        {
            switch (op.Type)
            {
            case ArmInstructionOperandType.Register:
                var reg = frame.EnsureRegister(A32Registers.RegisterByCapstoneID[op.RegisterValue.Value]);
                return(MaybeShiftOperand(reg, op));

            case ArmInstructionOperandType.SysRegister:
                var sysreg = frame.EnsureRegister(A32Registers.SysRegisterByCapstoneID[op.SysRegisterValue.Value]);
                return(sysreg);

            case ArmInstructionOperandType.Immediate:
                return(Constant.Word32(op.ImmediateValue.Value));

            case ArmInstructionOperandType.CImmediate:
            case ArmInstructionOperandType.PImmediate:
                return(Constant.Byte((byte)op.ImmediateValue.Value));

            case ArmInstructionOperandType.Memory:
                Expression baseReg = Reg(op.MemoryValue.BaseRegister);
                Expression ea      = baseReg;
                if (op.MemoryValue.BaseRegister
                    == ArmRegister.PC)  // PC-relative address
                {
                    var dst = (uint)((int)instrs.Current.Address.ToUInt32() + op.MemoryValue.Displacement) + 8u;
                    ea = Address.Ptr32(dst);
                    if (op.MemoryValue.IndexRegister != ArmRegister.Invalid)
                    {
                        var ireg = Reg(op.MemoryValue.IndexRegister);
                        if (op.Shifter.Type == ArmShifterType.LSL)
                        {
                            ea = m.IAdd(ea, m.IMul(ireg, 1 << op.Shifter.Value));
                        }
                        else
                        {
                            throw new NotImplementedException();
                        }
                    }
                    return(m.Load(SizeFromLoadStore(instr), ea));
                }
                if (op.MemoryValue.Displacement != 0 && instrs.Current.IsLastOperand(op))
                {
                    var offset = Constant.Int32(op.MemoryValue.Displacement);
                    ea = op.MemoryValue.IndexRegisterScale < 0
                        ? m.ISub(ea, offset)
                        : m.IAdd(ea, offset);
                }
                if (instrs.Current.IsLastOperand(op) && instr.ArchitectureDetail.WriteBack)
                {
                    m.Assign(baseReg, ea);
                    ea = baseReg;
                }
                return(m.Load(SizeFromLoadStore(instr), ea));

            case ArmInstructionOperandType.FloatingPoint:
                return(Constant.Real64(op.FloatingPointValue.Value));
            }
            throw new NotImplementedException(op.Type.ToString());
        }
示例#4
0
        private Expression RewriteOperand(Operand op)
        {
            Constant offset;

            switch (op.Mode)
            {
            default: throw new NotImplementedException("Unimplemented address mode " + op.Mode);

            case AddressMode.Accumulator:
                return(frame.EnsureRegister(Registers.a));

            case AddressMode.Immediate:
                return(op.Offset);

            case AddressMode.IndirectIndexed:
                var y = frame.EnsureRegister(Registers.y);
                offset = Constant.Word16((ushort)op.Offset.ToByte());
                return(emitter.LoadB(
                           emitter.IAdd(
                               emitter.Load(PrimitiveType.Ptr16, offset),
                               emitter.Cast(PrimitiveType.UInt16, y))));

            case AddressMode.IndexedIndirect:
                var x = frame.EnsureRegister(Registers.x);
                offset = Constant.Word16((ushort)op.Offset.ToByte());
                return(emitter.LoadB(
                           emitter.Load(
                               PrimitiveType.Ptr16,
                               emitter.IAdd(
                                   offset,
                                   emitter.Cast(PrimitiveType.UInt16, x)))));

            case AddressMode.Absolute:
                return(emitter.LoadB(op.Offset));

            case AddressMode.AbsoluteX:
                return(emitter.LoadB(emitter.IAdd(op.Offset, frame.EnsureRegister(Registers.x))));

            case AddressMode.ZeroPage:
                if (op.Register != null)
                {
                    return(emitter.LoadB(
                               emitter.IAdd(
                                   Constant.Create(PrimitiveType.Ptr16, op.Offset.ToUInt16()),
                                   frame.EnsureRegister(op.Register))));
                }
                else
                {
                    return(emitter.LoadB(
                               Constant.Create(PrimitiveType.Ptr16, op.Offset.ToUInt16())));
                }
            }
        }
示例#5
0
        private Expression RewriteSrc(MachineOperand op)
        {
            var reg = op as RegisterOperand;

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

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

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

            if (mem != null)
            {
                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.Cast(PrimitiveType.Int16, idx));
                    }
                    else if (mem.Offset != null)
                    {
                        ea = m.IAdd(
                            ea,
                            m.Int16((sbyte)mem.Offset.ToByte()));
                    }
                }
                else
                {
                    ea = arch.MakeAddressFromConstant(mem.Offset);
                }
                var tmp = binder.CreateTemporary(mem.Width);
                m.Assign(tmp, m.Load(mem.Width, ea));
                return(tmp);
            }
            throw new NotImplementedException(op.GetType().Name);
        }
示例#6
0
        private Expression RewriteOp(ArmInstructionOperand op, DataType accessSize = null)
        {
            switch (op.Type)
            {
            case ArmInstructionOperandType.Register:
                return(GetReg(op.RegisterValue.Value));

            case ArmInstructionOperandType.Immediate:
                if (accessSize != null)
                {
                    return(Constant.Create(accessSize, op.ImmediateValue.Value));
                }
                else
                {
                    return(Constant.Int32(op.ImmediateValue.Value));
                }

            case ArmInstructionOperandType.Memory:
                var mem = op.MemoryValue;
                var ea  = EffectiveAddress(mem);
                return(emitter.Load(accessSize, ea));

            default:
                throw new NotImplementedException(op.Type.ToString());
            }
        }
示例#7
0
        private void RewriteMem(int iOp, Expression src, Action <Expression, Expression> write, Expression seg)
        {
            var        op      = instr.operands[iOp];
            var        mop     = (MemoryOperand)op;
            var        baseReg = frame.EnsureRegister(mop.Base);
            Expression ea      = baseReg;

            if (mop.PreDecrement)
            {
                m.Assign(baseReg, m.ISub(baseReg, Constant.Int16(1)));
            }
            Expression val;

            if (seg != null)
            {
                val = m.SegMem(mop.Width, seg, ea);
            }
            else
            {
                val = m.Load(mop.Width, ea);
            }
            write(val, src);
            if (mop.PostIncrement)
            {
                m.Assign(baseReg, m.IAdd(baseReg, Constant.Int16(1)));
            }
        }
示例#8
0
        private Expression Rewrite(MachineOperand op, bool highWord = false)
        {
            var rop = op as RegisterOperand;

            if (rop != null)
            {
                if (rop.Register.Number == 31)
                {
                    return(Constant.Word64(0));
                }
                else if (rop.Register.Number == 63)
                {
                    return(Constant.Real64(0.0));
                }
                else
                {
                    return(this.binder.EnsureRegister(rop.Register));
                }
            }
            var imm = op as ImmediateOperand;

            if (imm != null)
            {
                return(imm.Value);
            }
            var addr = op as AddressOperand;

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

            if (mop != null)
            {
                int        offset = highWord ? (int)mop.Offset << 16 : mop.Offset;
                Expression ea;
                if (mop.Base.Number == ZeroRegister)
                {
                    var dt = PrimitiveType.Create(Domain.Integer, arch.PointerType.Size);
                    ea = Constant.Create(dt, offset); //$TODO should be platform size.
                }
                else
                {
                    ea = binder.EnsureRegister(mop.Base);
                    if (offset > 0)
                    {
                        ea = m.IAdd(ea, offset);
                    }
                    else if (offset < 0)
                    {
                        ea = m.ISub(ea, -offset);
                    }
                }
                return(m.Load(mop.Width, ea));
            }
            throw new NotImplementedException(string.Format("{0} ({1})", op, op.GetType().Name));
        }
示例#9
0
        private Expression RewriteOperand(MachineOperand op)
        {
            var regOp = op as RegisterOperand;

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

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

            if (indOp != null)
            {
                Expression ea;
                Identifier baseReg = binder.EnsureRegister(indOp.Base);
                if (indOp.Offset == 0)
                {
                    ea = baseReg;
                }
                else if (indOp.Offset > 0)
                {
                    ea = m.IAdd(baseReg, indOp.Offset);
                }
                else
                {
                    ea = m.ISub(baseReg, -indOp.Offset);
                }
                return(m.Load(indOp.Width, ea));
            }
            var addrOp = op as AddressOperand;

            if (addrOp != null)
            {
                return(addrOp.Address);
            }
            throw new NotImplementedException(string.Format("Rewriting of operand type {0} not implemented yet.", op.GetType().Name));
        }
示例#10
0
        private Expression Operand(ArmInstructionOperand op)
        {
            switch (op.Type)
            {
            case ArmInstructionOperandType.Register:
                var reg = frame.EnsureRegister(A32Registers.RegisterByCapstoneID[op.RegisterValue.Value]);
                return(MaybeShiftOperand(reg, op));

            case ArmInstructionOperandType.Immediate:
                return(Constant.Word32(op.ImmediateValue.Value));

            case ArmInstructionOperandType.Memory:
                Expression baseReg = Reg(op.MemoryValue.BaseRegister);
                Expression ea      = baseReg;
                if (op.MemoryValue.BaseRegister == ArmRegister.PC)  // PC-relative address
                {
                    if (op.MemoryValue.Displacement != 0)
                    {
                        var dst = (uint)((int)instrs.Current.Address.ToUInt32() + op.MemoryValue.Displacement) + 8u;
                        return(emitter.Load(SizeFromLoadStore(instr), Address.Ptr32(dst)));
                    }
                }
                if (op.MemoryValue.Displacement != 0 && instrs.Current.IsLastOperand(op))
                {
                    var offset = Constant.Int32(op.MemoryValue.Displacement);
                    ea = op.MemoryValue.IndexRegisterScale < 0
                        ? emitter.ISub(ea, offset)
                        : emitter.IAdd(ea, offset);
                }
                if (instrs.Current.IsLastOperand(op) && instr.ArchitectureDetail.WriteBack)
                {
                    emitter.Assign(baseReg, ea);
                    ea = baseReg;
                }
                return(emitter.Load(SizeFromLoadStore(instr), ea));
            }
            throw new NotImplementedException(op.Type.ToString());
        }
示例#11
0
        private Expression RewriteOp(MachineOperand op)
        {
            var rOp = op as RegisterOperand;

            if (rOp != null)
            {
                return(frame.EnsureRegister(rOp.Register));
            }
            var immOp = op as ImmediateOperand;

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

            if (memOp != null)
            {
                Identifier bReg = null;
                if (memOp.Base != null)
                {
                    bReg = frame.EnsureRegister(memOp.Base);
                }
                if (memOp.Offset == null)
                {
                    return(emitter.Load(memOp.Width, bReg));
                }
                else if (bReg == null)
                {
                    return(emitter.Load(memOp.Width, memOp.Offset));
                }
                else
                {
                    int s = memOp.Offset.ToInt32();
                    if (s > 0)
                    {
                        return(emitter.Load(memOp.Width, emitter.IAdd(bReg, s)));
                    }
                    else if (s < 0)
                    {
                        return(emitter.Load(memOp.Width, emitter.ISub(bReg, -s)));
                    }
                    else
                    {
                        return(emitter.Load(memOp.Width, bReg));
                    }
                }
            }
            throw new NotImplementedException(string.Format("Rewriting of Z80 operand type {0} is not implemented yet.", op.GetType().FullName));
        }
示例#12
0
        private Expression RewriteSrc(MachineOperand op)
        {
            var memOp = op as MemoryOperand;

            if (memOp != null)
            {
                var r   = frame.EnsureRegister(memOp.Register);
                var tmp = frame.CreateTemporary(op.Width);
                if (memOp.Mode == AddressMode.AutoIncr)
                {
                    emitter.Assign(tmp, emitter.Load(op.Width, r));
                    emitter.Assign(r, emitter.IAdd(r, memOp.Width.Size));
                    return(tmp);
                }
                return(tmp);
            }
            var regOp = op as RegisterOperand;

            if (regOp != null)
            {
                return(frame.EnsureRegister(regOp.Register));
            }
            throw new NotImplementedException();
        }
示例#13
0
        private Expression RewriteJmpSrc(MachineOperand op)
        {
            var memOp = op as MemoryOperand;

            if (memOp == null)
            {
                throw new AddressCorrelatedException(
                          instrs.Current.Address,
                          "Invalid addressing mode for transfer functions.",
                          memOp.Mode);
            }
            var r   = frame.EnsureRegister(memOp.Register);
            var tmp = frame.CreateTemporary(op.Width);

            switch (memOp.Mode)
            {
            default:
                throw new AddressCorrelatedException(
                          instrs.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.Load(op.Width, m.Load(PrimitiveType.Ptr16, r)));
                m.Assign(r, m.IAdd(r, memOp.Width.Size));
                break;

            case AddressMode.AutoIncrDef:
                m.Assign(tmp, m.Load(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.Load(op.Width, r));

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

            case AddressMode.Indexed:
                if (memOp.Register == Registers.pc)
                {
                    var offset   = (short)memOp.EffectiveAddress;
                    var addrBase = (long)rtlCluster.Address.ToLinear();
                    var addr     = Address.Ptr16((ushort)(2 + addrBase + offset));
                    return(addr);
                }
                else
                {
                    return(m.Load(
                               this.instrs.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)rtlCluster.Address.ToLinear() + rtlCluster.Length;
                    var addr     = Constant.Word16((ushort)(addrBase + offset));
                    return(m.Load(
                               PrimitiveType.Word16,
                               addr));
                }
                else
                {
                    return(m.Load(
                               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();
             */
        }
示例#14
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.Load(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.Load(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.Load(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.Load(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.LoadDw(ea);
                }
                if (indop.index_reg != null)
                {
                    var idx = Combine(null, indop.index_reg);
                    if (indop.index_scale > 1)
                    {
                        idx = m.IMul(idx, indop.index_scale);
                    }
                    ea = Combine(ea, idx);
                }
                if (indop.preindex)
                {
                    ea = m.LoadDw(ea);
                }
                ea = Combine(ea, indop.outer);
                return(m.Load(DataWidth, ea));
            }
            throw new NotImplementedException("Unimplemented RewriteSrc for operand type " + operand.GetType().Name);
        }
示例#15
0
        private Expression Operand(MachineOperand op)
        {
            var rop = op as RegisterOperand;

            if (rop != null)
            {
                return(frame.EnsureRegister(rop.Register));
            }
            var immOp = op as ImmediateOperand;

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

            if (shOp != null)
            {
                var r  = Operand(shOp.Operand);
                var sh = Operand(shOp.Shift);
                switch (shOp.Opcode)
                {
                case Opcode.lsl: return(emitter.Shl(r, sh));

                case Opcode.lsr: return(emitter.Shr(r, sh));

                case Opcode.asr: return(emitter.Sar(r, sh));

                case Opcode.ror: return(host.PseudoProcedure(PseudoProcedure.Ror, PrimitiveType.Word32, r, sh));

                default: throw new NotSupportedException(string.Format("Unsupported shift operation {0}.", shOp.Opcode));
                }
            }
            var memOp = op as ArmMemoryOperand;

            if (memOp != null)
            {
                Expression baseReg = frame.EnsureRegister(memOp.Base);
                Expression ea      = baseReg;
                if (memOp.Base.Number == 0x0F)  // PC-relative address
                {
                    var imm = memOp.Offset as ArmImmediateOperand;
                    if (imm != null)
                    {
                        if (memOp.Writeback)
                        {
                            throw new NotImplementedException();
                        }
                        var dst = (uint)((int)instr.Address.ToUInt32() + imm.Value.ToInt32()) + 8u;

                        return(emitter.Load(memOp.Width, Address.Ptr32(dst)));
                    }
                }
                if (memOp.Offset != null && memOp.Preindexed)
                {
                    var offset = Operand(memOp.Offset);
                    ea = memOp.Subtract
                        ? emitter.ISub(ea, offset)
                        : emitter.IAdd(ea, offset);
                }
                if (memOp.Preindexed && memOp.Writeback)
                {
                    emitter.Assign(baseReg, ea);
                    ea = baseReg;
                }
                return(emitter.Load(memOp.Width, ea));
            }
            throw new NotSupportedException(string.Format("Unsupported operand {0}.", op));
        }
示例#16
0
        private Expression RewriteSrcOp(int iOp, PrimitiveType width)
        {
            var op    = dasm.Current.Operands[iOp];
            var regOp = op as RegisterOperand;

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

                    var regLo = frame.EnsureSequence(regHi1.Storage, reg.Storage, PrimitiveType.Word64);
                    var regHi = frame.EnsureSequence(regHi3.Storage, regHi2.Storage, PrimitiveType.Word64);
                    return(frame.EnsureSequence(regHi.Storage, regLo.Storage, width));
                }
                else
                {
                    return(emitter.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 = frame.EnsureRegister(memOp.Base);
                    if (memOp.AutoDecrement)
                    {
                        emitter.Assign(reg, emitter.ISub(reg, width.Size));
                    }
                    else if (memOp.AutoIncrement)
                    {
                        var tmp = frame.CreateTemporary(reg.DataType);
                        emitter.Assign(tmp, reg);
                        reg = tmp;
                    }
                    ea = reg;
                    if (memOp.Offset != null)
                    {
                        ea = emitter.IAdd(ea, memOp.Offset);
                    }
                    if (memOp.Index != null)
                    {
                        Expression idx = frame.EnsureRegister(memOp.Index);
                        if (width.Size != 1)
                        {
                            idx = emitter.IMul(idx, Constant.Int32(width.Size));
                        }
                        ea = emitter.IAdd(ea, idx);
                    }
                    Expression load;
                    if (memOp.Deferred)
                    {
                        load = emitter.Load(width, emitter.LoadDw(ea));
                    }
                    else
                    {
                        load = emitter.Load(width, ea);
                    }
                    if (memOp.AutoIncrement)
                    {
                        if (memOp.AutoIncrement)
                        {
                            reg = frame.EnsureRegister(memOp.Base);
                            int inc = (memOp.Deferred) ? 4 : width.Size;
                            emitter.Assign(reg, emitter.IAdd(reg, inc));
                        }
                    }
                    return(load);
                }
                else
                {
                }
            }
            var addrOp = op as AddressOperand;

            if (addrOp != null)
            {
                return(addrOp.Address);
            }
            throw new NotImplementedException(op.GetType().Name);
        }
示例#17
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.Load(mem.Width, binder.EnsureRegister(mem.reg)));

                case AddressingMode.IndirectPreDecr:
                    reg = binder.EnsureRegister(mem.reg);
                    m.Assign(reg, m.IAdd(reg, Constant.Int32(mem.Width.Size)));
                    return(m.Load(mem.Width, reg));

                case AddressingMode.IndirectPostIncr:
                    var t = binder.CreateTemporary(mem.Width);
                    reg = binder.EnsureRegister(mem.reg);
                    m.Assign(t, m.Load(mem.Width, reg));
                    m.Assign(reg, m.IAdd(reg, Constant.Int32(t.DataType.Size)));
                    return(t);

                case AddressingMode.IndirectDisplacement:
                    reg = binder.EnsureRegister(mem.reg);
                    return(m.Load(
                               mem.Width,
                               m.IAdd(reg, Constant.Int32(mem.disp))));

                case AddressingMode.IndexedIndirect:
                    return(m.Load(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.Load(mem.Width, Address.Ptr32(addr)));
                }
            }
            throw new NotImplementedException(op.GetType().Name);
        }